home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr25 / dkb32.zip / DKB32SRC.ZIP / PARSE.C < prev    next >
C/C++ Source or Header  |  1991-05-07  |  76KB  |  2,629 lines

  1. /*****************************************************************************
  2. *
  3. *                                    parse.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module implements a parser for the scene description files.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulletin boards:
  35. *
  36. *     OMX              (613) 731-3419
  37. *     Mystic           (613) 596-4249  or  (613) 596-4772
  38. *
  39. *  Fidonet:   1:163/109.9
  40. *  Internet:  dbuck@ccs.carleton.ca
  41. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     The "You Can Call Me RAY" BBS (708) 358-5611
  46. *     The Information Exchange BBS  (708) 945-5575
  47. *
  48. *****************************************************************************/
  49.  
  50. #include "frame.h"
  51. #include "vector.h"
  52. #include "dkbproto.h"
  53.  
  54. /* This file implements a simple recursive-descent parser for reading the
  55. input file.  */
  56.  
  57. FRAME *Parsing_Frame_Ptr;
  58.  
  59. extern METHODS Composite_Methods;
  60. extern METHODS Basic_Object_Methods;
  61. extern METHODS Sphere_Methods;
  62. extern METHODS Quadric_Methods;
  63. extern METHODS Quartic_Methods;
  64. extern METHODS Viewpoint_Methods;
  65. extern METHODS Plane_Methods;
  66. extern METHODS Triangle_Methods;
  67. extern METHODS Smooth_Triangle_Methods;
  68. extern METHODS CSG_Union_Methods;
  69. extern METHODS CSG_Intersection_Methods;
  70.  
  71. extern struct Reserved_Word_Struct Reserved_Words [];
  72. extern DBL Antialias_Threshold;
  73.  
  74. extern struct Token_Struct Token;
  75.  
  76. #define MAX_CONSTANTS 250
  77. struct Constant_Struct Constants[MAX_CONSTANTS];
  78. int Number_Of_Constants;
  79. TEXTURE *Default_Texture;
  80. int Degenerate_Triangles;
  81.  
  82. /* Here we create out own little language for doing the parsing.  It
  83. makes the code easier to read. */
  84.  
  85. #define EXPECT { int Exit_Flag; Exit_Flag = FALSE; \
  86.  while (!Exit_Flag) {Get_Token();  switch (Token.Token_Id) {
  87. #define CASE(x) case x:
  88. #define CASE2(x, y) case x: case y:
  89. #define CASE3(x, y, z) case x: case y: case z:
  90. #define CASE4(w, x, y, z) case w: case x: case y: case z:
  91. #define CASE5(v, w, x, y, z) case v: case w: case x: case y: case z:
  92. #define CASE6(u, v, w, x, y, z) case u: case v: case w: case x: case y: case z:
  93. #define END_CASE break;
  94. #define EXIT Exit_Flag = TRUE;
  95. #define OTHERWISE default:
  96. #define END_EXPECT } } }
  97. #define GET(x) Get_Token(); if (Token.Token_Id != x) Parse_Error (x)
  98. #define UNGET Unget_Token();
  99.  
  100. /*
  101.  
  102. char *Coeff_terms[35] = {
  103.    "x^4", "x^3*y", "x^3*z", "x^3", "x^2*y^2", "x^2*y*z", "x^2*y", "x^2*z^2",
  104.    "x^2*z", "x^2", "x*y^3", "x*y^2*z", "x*y^2", "x*y*z^2", "x*y*z", "x*y",
  105.    "x*z^3", "x*z^2", "x*z", "x", "y^4", "y^3*z", "y^3", "y^2*z^2", "y^2*z",
  106.    "y^2", "y*z^3", "y*z^2", "y*z", "y", "z^4", "z^3", "z^2", "z", ""
  107.    };
  108.  
  109. void show_quartic(Coeffs)
  110. DBL *Coeffs;
  111. {
  112.    int i,j;
  113.    for (i=0,j=0;i<35;i++)
  114.       if (Coeffs[i] != 0.0) {
  115.      if (j) printf(" + ");
  116.      printf("%.5Lg %s", Coeffs[i], Coeff_terms[i]);
  117.      j = 1;
  118.      }
  119. }
  120.  
  121. */
  122.  
  123. /* Parse the file into the given frame. */
  124. void Parse (Frame_Ptr)
  125.   FRAME *Frame_Ptr;
  126.   {
  127.   Parsing_Frame_Ptr = Frame_Ptr;
  128.  
  129.   Degenerate_Triangles = FALSE;
  130.   Token_Init ();
  131.   Frame_Init ();
  132.   Parse_Frame ();
  133.   if (Degenerate_Triangles) {
  134.      fprintf (stderr, "Cannot continue due to degenerate triangles.\n");
  135.      exit(1);
  136.      }
  137.   }
  138.  
  139. void Token_Init ()
  140.   {
  141.   Number_Of_Constants = 0;
  142.   }
  143.  
  144.  
  145. /* Set up the fields in the frame to default values. */
  146. void Frame_Init ()
  147.   {
  148.   Default_Texture = Get_Texture();
  149.   Init_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  150.   Parsing_Frame_Ptr -> Light_Sources = NULL;
  151.   Parsing_Frame_Ptr -> Objects = NULL;
  152.   Parsing_Frame_Ptr -> Atmosphere_IOR = 1.0;
  153.   Parsing_Frame_Ptr -> Antialias_Threshold = Antialias_Threshold;
  154.   Parsing_Frame_Ptr -> Fog_Distance = 0.0;
  155.   Make_Colour (&(Parsing_Frame_Ptr->Fog_Colour), 0.0, 0.0, 0.0);
  156.   }
  157.  
  158. /* Allocate and initialize a composite object. */
  159. COMPOSITE *Get_Composite_Object()
  160.   {
  161.   COMPOSITE *New_Composite;
  162.  
  163.   if ((New_Composite = (COMPOSITE *) malloc (sizeof (COMPOSITE)))
  164.         == NULL)
  165.     Error ("Cannot allocate object");
  166.  
  167.   New_Composite -> Objects = NULL;
  168.   New_Composite -> Next_Object = NULL;
  169.   New_Composite -> Next_Light_Source = NULL;
  170.   New_Composite -> Bounding_Shapes = NULL;
  171.   New_Composite -> Type = COMPOSITE_TYPE;
  172.   New_Composite -> Methods = &Composite_Methods;
  173.   return (New_Composite);
  174.   }
  175.  
  176. /* Allocate and initialize a sphere. */
  177. SPHERE *Get_Sphere_Shape()
  178.   {
  179.   SPHERE *New_Shape;
  180.  
  181.   if ((New_Shape = (SPHERE *) malloc (sizeof (SPHERE))) == NULL)
  182.     Error ("Cannot allocate shape");
  183.  
  184.   Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0);
  185.   New_Shape->Radius = 1.0;
  186.   New_Shape->Radius_Squared = 1.0;
  187.   New_Shape->Inverse_Radius = 1.0;
  188.   New_Shape -> Type = SPHERE_TYPE;
  189.   New_Shape -> Next_Object = NULL;
  190.   New_Shape -> Methods = &Sphere_Methods;
  191.   New_Shape -> VPCached = FALSE;
  192.   New_Shape -> Inverted = FALSE;
  193.   New_Shape -> Shape_Texture = NULL;
  194.   New_Shape -> Shape_Colour = NULL;
  195.   return (New_Shape);
  196.   }
  197.  
  198. /* Allocate and initialize a quadric surface. */
  199. QUADRIC *Get_Quadric_Shape()
  200.   {
  201.   QUADRIC *New_Shape;
  202.  
  203.   if ((New_Shape = (QUADRIC *) malloc (sizeof (QUADRIC))) == NULL)
  204.     Error ("Cannot allocate shape");
  205.  
  206.   Make_Vector (&(New_Shape -> Object_2_Terms), 1.0, 1.0, 1.0);
  207.   Make_Vector (&(New_Shape -> Object_Mixed_Terms), 0.0, 0.0, 0.0);
  208.   Make_Vector (&(New_Shape -> Object_Terms), 0.0, 0.0, 0.0);
  209.   New_Shape -> Object_Constant = 1.0;
  210.   New_Shape -> Object_VP_Constant = HUGE_VAL;
  211.   New_Shape -> Constant_Cached = FALSE;
  212.   New_Shape -> Non_Zero_Square_Term = FALSE;
  213.   New_Shape -> Type = QUADRIC_TYPE;
  214.   New_Shape -> Next_Object = NULL;
  215.   New_Shape -> Methods = &Quadric_Methods;
  216.   New_Shape -> Shape_Texture = NULL;
  217.   New_Shape -> Shape_Colour = NULL;
  218.   return (New_Shape);
  219.   }
  220.  
  221. /* Allocate and initialize a quartic surface. */
  222. QUARTIC *Get_Quartic_Shape()
  223. {
  224.    QUARTIC *New_Shape;
  225.    int i;
  226.  
  227.    if ((New_Shape = (QUARTIC *) malloc (sizeof (QUARTIC))) == NULL)
  228.       Error ("Cannot allocate shape");
  229.  
  230.    for (i=0;i<35;i++)
  231.       New_Shape->Coeffs[i] = 0.0;
  232.    New_Shape -> Type = QUARTIC_TYPE;
  233.    New_Shape -> Next_Object = NULL;
  234.    New_Shape -> Methods = &Quartic_Methods;
  235.    New_Shape -> Shape_Texture = NULL;
  236.    New_Shape -> Shape_Colour = NULL;
  237.    return (New_Shape);
  238. }
  239.  
  240. /* Allocate and initialize a plane. */
  241. PLANE *Get_Plane_Shape()
  242.   {
  243.   PLANE *New_Shape;
  244.  
  245.   if ((New_Shape = (PLANE *) malloc (sizeof (PLANE))) == NULL)
  246.     Error ("Cannot allocate shape");
  247.  
  248.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  249.   New_Shape->Distance = 0.0;
  250.   New_Shape -> Type = PLANE_TYPE;
  251.   New_Shape -> Next_Object = NULL;
  252.   New_Shape -> Methods = &Plane_Methods;
  253.   New_Shape -> VPCached = 0;
  254.   New_Shape -> Shape_Texture = NULL;
  255.   New_Shape -> Shape_Colour = NULL;
  256.   return (New_Shape);
  257.   }
  258.  
  259. /* Allocate and initialize a triangle. */
  260. TRIANGLE *Get_Triangle_Shape()
  261.   {
  262.   TRIANGLE *New_Shape;
  263.  
  264.   if ((New_Shape = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL)
  265.     Error ("Cannot allocate shape");
  266.  
  267.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  268.   Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  269.   Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  270.   Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  271.   New_Shape->Distance = 0.0;
  272.   New_Shape->Inverted = FALSE;
  273.   New_Shape -> Type = TRIANGLE_TYPE;
  274.   New_Shape -> Next_Object = NULL;
  275.   New_Shape -> Methods = &Triangle_Methods;
  276.   New_Shape -> VPCached = FALSE;
  277.   New_Shape -> Shape_Texture = NULL;
  278.   New_Shape -> Shape_Colour = NULL;
  279.   return (New_Shape);
  280.   }
  281.  
  282. /* Allocate and initialize a smooth triangle. */
  283. SMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape()
  284.   {
  285.   SMOOTH_TRIANGLE *New_Shape;
  286.  
  287.   if ((New_Shape = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL)
  288.     Error ("Cannot allocate shape");
  289.  
  290.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  291.   Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  292.   Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  293.   Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  294.   Make_Vector (&(New_Shape -> N1), 0.0, 1.0, 0.0);
  295.   Make_Vector (&(New_Shape -> N2), 0.0, 1.0, 0.0);
  296.   Make_Vector (&(New_Shape -> N3), 0.0, 1.0, 0.0);
  297.   New_Shape->Distance = 0.0;
  298.   New_Shape -> Type = SMOOTH_TRIANGLE_TYPE;
  299.   New_Shape->Inverted = FALSE;
  300.   New_Shape -> Next_Object = NULL;
  301.   New_Shape -> Methods = &Smooth_Triangle_Methods;
  302.   New_Shape -> VPCached = 0;
  303.   New_Shape -> Shape_Texture = NULL;
  304.   New_Shape -> Shape_Colour = NULL;
  305.   return (New_Shape);
  306.   }
  307.  
  308. CSG_SHAPE *Get_CSG_Shape()
  309.   {
  310.   CSG_SHAPE *New_Shape;
  311.  
  312.   if ((New_Shape = (CSG_SHAPE *) malloc (sizeof (CSG_SHAPE))) == NULL)
  313.     Error ("Cannot allocate shape");
  314.  
  315.   New_Shape -> Parent_Object = NULL;
  316.   New_Shape -> Next_Object = NULL;
  317.   New_Shape -> Shapes = NULL;
  318.   return (New_Shape);
  319.   }
  320.  
  321. CSG_SHAPE *Get_CSG_Union()
  322.   {
  323.   CSG_SHAPE *New_Shape;
  324.  
  325.   New_Shape = Get_CSG_Shape();
  326.   New_Shape -> Methods = &CSG_Union_Methods;
  327.   New_Shape -> Type = CSG_UNION_TYPE;
  328.   return (New_Shape);
  329.   }
  330.  
  331. CSG_SHAPE *Get_CSG_Intersection()
  332.   {
  333.   CSG_SHAPE *New_Shape;
  334.  
  335.   New_Shape = Get_CSG_Shape();
  336.   New_Shape -> Methods = &CSG_Intersection_Methods;
  337.   New_Shape -> Type = CSG_INTERSECTION_TYPE;
  338.   return (New_Shape);
  339.   }
  340.  
  341. OBJECT *Get_Object ()
  342.   {
  343.   OBJECT *New_Object;
  344.  
  345.   if ((New_Object = (OBJECT *) malloc (sizeof (OBJECT))) == NULL)
  346.     Error ("Cannot allocate object");
  347.  
  348.   Make_Vector (&(New_Object -> Object_Center), 0.0, 0.0, 0.0);
  349.  
  350.   New_Object -> Next_Object = NULL;
  351.   New_Object -> Next_Light_Source = NULL;
  352.   New_Object -> Shape = NULL;
  353.   New_Object -> Bounding_Shapes = NULL;
  354.   New_Object -> Object_Texture = Default_Texture;
  355.  
  356.   New_Object->Object_Colour = NULL;
  357.  
  358.   New_Object -> Light_Source_Flag = FALSE;
  359.   New_Object -> Type = OBJECT_TYPE;
  360.   New_Object -> Methods = &Basic_Object_Methods;
  361.   return (New_Object);
  362.   }
  363.  
  364. TEXTURE *Get_Texture ()
  365.    {
  366.    TEXTURE *New_Texture;
  367.  
  368.    if ((New_Texture = (TEXTURE *) malloc (sizeof (TEXTURE))) == NULL)
  369.      Error ("Cannot allocate object");
  370.  
  371.    New_Texture -> Next_Texture = NULL;
  372.    New_Texture -> Object_Reflection = 0.0;
  373.    New_Texture -> Object_Ambient = 0.3;
  374.    New_Texture -> Object_Diffuse = 0.7;
  375.    New_Texture -> Object_Brilliance = 1.0;
  376.    New_Texture -> Object_Specular = 0.0;
  377.    New_Texture -> Object_Roughness = 0.05;
  378.    New_Texture -> Object_Phong = 0.0;
  379.    New_Texture -> Object_PhongSize = 40;
  380.  
  381.    New_Texture -> Texture_Randomness= 0.0;
  382.    New_Texture -> Bump_Amount = 0.0;
  383.    New_Texture -> Phase = 0.0;
  384.    New_Texture -> Frequency = 1.0;
  385.    New_Texture -> Texture_Number = NO_TEXTURE;
  386.    New_Texture -> Texture_Transformation = NULL;
  387.    New_Texture -> Bump_Number = NO_BUMPS;
  388.    New_Texture -> Turbulence = 0.0;
  389.    New_Texture -> Colour_Map = NULL;
  390.    New_Texture -> Once_Flag = FALSE;
  391.    New_Texture -> Metallic_Flag = FALSE;
  392.  
  393.    New_Texture -> Constant_Flag = TRUE;
  394.    New_Texture -> Colour1 = NULL;
  395.    New_Texture -> Colour2 = NULL;
  396.    Make_Vector (&New_Texture->Texture_Gradient, 0.0, 0.0, 0.0);
  397.  
  398.    New_Texture -> Object_Index_Of_Refraction = 1.0;
  399.    New_Texture -> Object_Refraction = 0.0;
  400.  
  401.    return (New_Texture);
  402.    }
  403.  
  404. VIEWPOINT *Get_Viewpoint ()
  405.   {
  406.   VIEWPOINT *New_Viewpoint;
  407.  
  408.   if ((New_Viewpoint = (VIEWPOINT *)malloc (sizeof (VIEWPOINT)))
  409.         == NULL)
  410.     Error ("Cannot allocate viewpoint");
  411.  
  412.   Init_Viewpoint (New_Viewpoint);
  413.   return (New_Viewpoint);
  414.   }
  415.  
  416. COLOUR *Get_Colour ()
  417.   {
  418.   COLOUR *New_Colour;
  419.  
  420.   if ((New_Colour = (COLOUR *) malloc (sizeof (COLOUR))) == NULL)
  421.     Error ("Cannot allocate colour");
  422.  
  423.   Make_Colour (New_Colour, 0.0, 0.0, 0.0);
  424.   return (New_Colour);
  425.   }
  426.  
  427. VECTOR *Get_Vector ()
  428.   {
  429.   VECTOR *New_Vector;
  430.  
  431.   if ((New_Vector = (VECTOR *) malloc (sizeof (VECTOR))) == NULL)
  432.     Error ("Cannot allocate vector");
  433.  
  434.   New_Vector -> x = 0.0;
  435.   New_Vector -> y = 0.0;
  436.   New_Vector -> z = 0.0;
  437.   return (New_Vector);
  438.   }
  439.  
  440. DBL *Get_Float ()
  441.   {
  442.   DBL *New_Float;
  443.  
  444.   if ((New_Float = (DBL *) malloc (sizeof (DBL))) == NULL)
  445.     Error ("Cannot allocate float");
  446.  
  447.   *New_Float = 0.0;
  448.   return (New_Float);
  449.   }
  450.  
  451. TRANSFORMATION *Get_Transformation()
  452.   {
  453.   TRANSFORMATION *New_Transformation;
  454.  
  455.   if ((New_Transformation =
  456.         (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  457.     Error ("Cannot allocate transformation");
  458.  
  459.   MIdentity ((MATRIX *) &(New_Transformation -> matrix[0][0]));
  460.   MIdentity ((MATRIX *) &(New_Transformation -> inverse[0][0]));
  461.   return (New_Transformation);
  462.   }
  463.  
  464. /* Parse a float.  Doesn't handle exponentiation. */
  465. DBL Parse_Float ()
  466.   {
  467.   DBL Local_Float = 0.0;
  468.   CONSTANT Constant_Id;
  469.   register int Negative, Sign_Parsed;
  470.  
  471.   Negative = FALSE;
  472.   Sign_Parsed = FALSE;
  473.  
  474.   EXPECT
  475.     CASE (IDENTIFIER_TOKEN)
  476.       if ((Constant_Id = Find_Constant()) != -1)
  477.         if (Constants[(int)Constant_Id].Constant_Type == FLOAT_CONSTANT)
  478.           {
  479.           Local_Float = *((DBL *) Constants[(int)Constant_Id].Constant_Data);
  480.           if (Negative)
  481.             Local_Float *= -1.0;
  482.           }
  483.         else
  484.           Type_Error ();
  485.       else
  486.         Undeclared ();
  487.       EXIT
  488.     END_CASE
  489.  
  490.     CASE (PLUS_TOKEN)
  491.       if (Sign_Parsed)
  492.         Parse_Error (FLOAT_TOKEN);
  493.       Sign_Parsed = TRUE;
  494.     END_CASE
  495.  
  496.     CASE (DASH_TOKEN)
  497.       if (Sign_Parsed)
  498.         Parse_Error (FLOAT_TOKEN);
  499.       Negative = TRUE;
  500.       Sign_Parsed = TRUE;
  501.     END_CASE
  502.  
  503.     CASE (FLOAT_TOKEN)
  504.       Local_Float = Token.Token_Float;
  505.       if (Negative)
  506.         Local_Float *= -1.0;
  507.       EXIT
  508.     END_CASE
  509.  
  510.     OTHERWISE
  511.       Parse_Error (FLOAT_TOKEN);
  512.     END_CASE
  513.   END_EXPECT
  514.  
  515.   return (Local_Float);
  516.   }
  517.  
  518. void Parse_Vector (Given_Vector)
  519.   VECTOR *Given_Vector;
  520.   {
  521.   CONSTANT Constant_Id;
  522.  
  523.   EXPECT
  524.     CASE (IDENTIFIER_TOKEN)
  525.       if ((Constant_Id = Find_Constant()) != -1)
  526.         if (Constants[(int)Constant_Id].Constant_Type == VECTOR_CONSTANT)
  527.           *Given_Vector = *((VECTOR *) Constants[(int)Constant_Id].Constant_Data);
  528.         else
  529.           Type_Error ();
  530.       else
  531.         Undeclared ();
  532.       EXIT
  533.     END_CASE
  534.  
  535.     CASE (LEFT_ANGLE_TOKEN)
  536.       (Given_Vector -> x) = Parse_Float();
  537.       (Given_Vector -> y) = Parse_Float();
  538.       (Given_Vector -> z) = Parse_Float();
  539.       GET (RIGHT_ANGLE_TOKEN);
  540.       EXIT
  541.     END_CASE
  542.  
  543.     OTHERWISE 
  544.       Parse_Error (LEFT_ANGLE_TOKEN);
  545.     END_CASE
  546.   END_EXPECT
  547.   }
  548.  
  549. void Parse_Coeffs(Given_Coeffs)
  550.   DBL *Given_Coeffs;
  551.   {
  552.   int i;
  553.  
  554.   EXPECT
  555.     CASE (LEFT_ANGLE_TOKEN)
  556.        for (i=0;i<35;i++)
  557.      Given_Coeffs[i] = Parse_Float();
  558.       GET (RIGHT_ANGLE_TOKEN);
  559.       EXIT
  560.     END_CASE
  561.  
  562.     OTHERWISE 
  563.       Parse_Error (LEFT_ANGLE_TOKEN);
  564.     END_CASE
  565.   END_EXPECT
  566. }
  567.  
  568. void Parse_Colour (Given_Colour)
  569.   COLOUR *Given_Colour;
  570.   {
  571.   CONSTANT Constant_Id;
  572.  
  573.   Make_Colour (Given_Colour, 0.0, 0.0, 0.0);
  574.   EXPECT
  575.     CASE (IDENTIFIER_TOKEN)
  576.       if ((Constant_Id = Find_Constant()) != -1)
  577.         if (Constants[(int)Constant_Id].Constant_Type == COLOUR_CONSTANT)
  578.           *Given_Colour = *((COLOUR *) Constants[(int)Constant_Id].Constant_Data);
  579.         else
  580.           Type_Error ();
  581.       else
  582.         Undeclared ();
  583.     END_CASE
  584.  
  585.     CASE (RED_TOKEN)
  586.       (Given_Colour -> Red) = Parse_Float();
  587.     END_CASE
  588.  
  589.     CASE (GREEN_TOKEN)
  590.       (Given_Colour -> Green) = Parse_Float();
  591.     END_CASE
  592.  
  593.     CASE (BLUE_TOKEN)
  594.       (Given_Colour -> Blue) = Parse_Float();
  595.     END_CASE
  596.  
  597.     CASE (ALPHA_TOKEN)
  598.       (Given_Colour -> Alpha) = Parse_Float();
  599.     END_CASE
  600.  
  601.     OTHERWISE
  602.       UNGET
  603.       EXIT
  604.     END_CASE
  605.   END_EXPECT
  606.   }
  607.  
  608. COLOUR_MAP *Parse_Colour_Map ()
  609.    {
  610. #define MAX_ENTRIES 20
  611.    COLOUR_MAP *New_Colour_Map;
  612. static COLOUR_MAP_ENTRY *Construction_Map = NULL;
  613.  
  614.    register int i, j;
  615.  
  616.    if ((New_Colour_Map = (COLOUR_MAP *) malloc (sizeof (COLOUR_MAP))) == NULL)
  617.       Error ("Not enough memory for colour map");
  618.  
  619.  
  620.    if (Construction_Map == NULL)
  621.       if ((Construction_Map = (COLOUR_MAP_ENTRY *)
  622.                      malloc(MAX_ENTRIES * sizeof (COLOUR_MAP_ENTRY))) == NULL)
  623.          Error ("Not enough memory for colour map");
  624.  
  625.    i = 0;
  626.    New_Colour_Map->Transparency_Flag = FALSE;
  627.  
  628.    EXPECT
  629.       CASE (LEFT_SQUARE_TOKEN)
  630.          Construction_Map [i].start = Parse_Float();
  631.          Construction_Map [i].end = Parse_Float();
  632.  
  633.          GET (COLOUR_TOKEN);
  634.          Parse_Colour (&(Construction_Map[i].Start_Colour));
  635.          if (Construction_Map[i].Start_Colour.Alpha != 0.0)
  636.             New_Colour_Map->Transparency_Flag = TRUE;
  637.  
  638.          GET (COLOUR_TOKEN);
  639.          Parse_Colour (&(Construction_Map[i].End_Colour));
  640.          if (Construction_Map[i].End_Colour.Alpha != 0.0)
  641.             New_Colour_Map->Transparency_Flag = TRUE;
  642.  
  643.          i++;
  644.          if (i > MAX_ENTRIES)
  645.             Error ("Colour_Map too long");
  646.          GET (RIGHT_SQUARE_TOKEN);
  647.       END_CASE
  648.  
  649.       CASE (END_COLOUR_MAP_TOKEN)
  650.           New_Colour_Map -> Number_Of_Entries = i;
  651.  
  652.           if ((New_Colour_Map -> Colour_Map_Entries = (COLOUR_MAP_ENTRY *)
  653.                malloc(sizeof(COLOUR_MAP_ENTRY) * i)) == NULL)
  654.              Error ("Not enough memory for colour map");
  655.  
  656.           for (j = 0 ; j < i ; j++)
  657.              New_Colour_Map->Colour_Map_Entries[j] = Construction_Map[j];
  658.  
  659.           EXIT
  660.       END_CASE
  661.  
  662.       OTHERWISE
  663.          Parse_Error (END_COLOUR_MAP_TOKEN);
  664.       END_CASE
  665.    END_EXPECT
  666.  
  667.    return (New_Colour_Map);
  668.    }
  669.  
  670. TEXTURE *Copy_Texture (Texture)
  671.    TEXTURE *Texture;
  672.    {
  673.    TEXTURE *New_Texture, *Local_Texture, *First_Texture, *Previous_Texture;
  674.  
  675.    Previous_Texture = First_Texture = NULL;
  676.  
  677.    for (Local_Texture = Texture ; Local_Texture != NULL ; Local_Texture = Local_Texture->Next_Texture)  {
  678.       New_Texture = Get_Texture();
  679.       *New_Texture = *Local_Texture;
  680.  
  681.       if (First_Texture == NULL)
  682.          First_Texture = New_Texture;
  683.  
  684.       if (Previous_Texture != NULL)
  685.          Previous_Texture->Next_Texture = New_Texture;
  686.  
  687.       if (New_Texture->Texture_Transformation) {
  688.          if ((New_Texture->Texture_Transformation = (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  689.         Error("Cannot allocate texture transformation");
  690.          *New_Texture->Texture_Transformation = *Local_Texture->Texture_Transformation;
  691.          }
  692.       New_Texture->Constant_Flag = FALSE;
  693.       Previous_Texture = New_Texture;
  694.       }   
  695.    return (First_Texture);
  696.    }
  697.  
  698. TEXTURE *Parse_Texture ()
  699.    {
  700.    VECTOR Local_Vector;
  701.    TRANSFORMATION Local_Transformation;
  702.    CONSTANT Constant_Id;
  703.    TEXTURE *Texture, *Local_Texture;
  704.    int reg;
  705.  
  706.    Texture = Default_Texture;
  707.  
  708.    EXPECT
  709.       CASE (IDENTIFIER_TOKEN)
  710.          if ((Constant_Id = Find_Constant()) != -1)
  711.             if (Constants[(int)Constant_Id].Constant_Type == TEXTURE_CONSTANT) {
  712.                Texture = ((TEXTURE *) Constants[(int)Constant_Id].Constant_Data);
  713.                }
  714.             else
  715.                Type_Error ();
  716.          else
  717.             Undeclared ();
  718.       END_CASE
  719.  
  720.       CASE (FLOAT_TOKEN)
  721.          UNGET
  722.          if (Texture->Constant_Flag) {
  723.             Texture = Copy_Texture(Texture);
  724.             Texture->Constant_Flag = FALSE;
  725.             }
  726.          Texture -> Texture_Randomness = Parse_Float();
  727.       END_CASE
  728.  
  729.       CASE (ONCE_TOKEN)
  730.          if (Texture->Constant_Flag) {
  731.             Texture = Copy_Texture(Texture);
  732.             Texture->Constant_Flag = FALSE;
  733.             }
  734.          Texture->Once_Flag = TRUE;
  735.       END_CASE
  736.  
  737.       CASE (TURBULENCE_TOKEN)
  738.          if (Texture->Constant_Flag) {
  739.             Texture = Copy_Texture(Texture);
  740.             Texture->Constant_Flag = FALSE;
  741.             }
  742.           Texture -> Turbulence = Parse_Float();
  743.       END_CASE
  744.  
  745.       CASE (BOZO_TOKEN)
  746.          if (Texture->Constant_Flag) {
  747.             Texture = Copy_Texture (Texture);
  748.             Texture->Constant_Flag = FALSE;
  749.             }
  750.          Texture -> Texture_Number = BOZO_TEXTURE;
  751.       END_CASE
  752.  
  753.       CASE (CHECKER_TOKEN)
  754.          if (Texture->Constant_Flag) {
  755.             Texture = Copy_Texture (Texture);
  756.             Texture->Constant_Flag = FALSE;
  757.             }
  758.          Texture -> Texture_Number = CHECKER_TEXTURE;
  759.          EXPECT
  760.             CASE (COLOUR_TOKEN)
  761.                Texture->Colour1 = Get_Colour();
  762.                Texture->Colour2 = Get_Colour();
  763.                Parse_Colour (Texture -> Colour1);
  764.                GET (COLOUR_TOKEN);
  765.                Parse_Colour (Texture -> Colour2);
  766.             END_CASE
  767.  
  768.             OTHERWISE
  769.                UNGET
  770.                EXIT
  771.             END_CASE
  772.          END_EXPECT
  773.       END_CASE
  774.  
  775.       CASE (CHECKER_TEXTURE_TOKEN)
  776.          if (Texture->Constant_Flag) {
  777.             Texture = Copy_Texture (Texture);
  778.             Texture->Constant_Flag = FALSE;
  779.             }
  780.          Texture -> Texture_Number = CHECKER_TEXTURE_TEXTURE;
  781.          EXPECT
  782.             CASE (TEXTURE_TOKEN)
  783.                Local_Texture = Parse_Texture ();
  784.                if (Local_Texture->Constant_Flag)
  785.                   Local_Texture = Copy_Texture(Local_Texture);
  786.  
  787.                {
  788.                TEXTURE *temp_texture;
  789.  
  790.                for (temp_texture = Local_Texture ;
  791.                     temp_texture->Next_Texture != NULL ;
  792.                     temp_texture = temp_texture->Next_Texture)
  793.                    {}
  794.  
  795.                temp_texture->Next_Texture = (TEXTURE *) Texture->Colour1;
  796.                Texture->Colour1 = (COLOUR *) Local_Texture;
  797.                }
  798.              END_CASE
  799.              OTHERWISE
  800.                 UNGET
  801.                 EXIT
  802.              END_CASE
  803.          END_EXPECT
  804.  
  805.          GET (TILE2_TOKEN);
  806.          EXPECT
  807.             CASE (TEXTURE_TOKEN)
  808.                Local_Texture = Parse_Texture ();
  809.                if (Local_Texture->Constant_Flag)
  810.                   Local_Texture = Copy_Texture(Local_Texture);
  811.  
  812.                {
  813.                TEXTURE *temp_texture;
  814.  
  815.                for (temp_texture = Local_Texture ;
  816.                     temp_texture->Next_Texture != NULL ;
  817.                     temp_texture = temp_texture->Next_Texture)
  818.                    {}
  819.  
  820.                temp_texture->Next_Texture = (TEXTURE *) Texture->Colour2;
  821.                Texture->Colour2 = (COLOUR *) Local_Texture;
  822.                }
  823.              END_CASE
  824.              OTHERWISE
  825.                 UNGET
  826.                 EXIT
  827.              END_CASE
  828.          END_EXPECT
  829.          GET (END_CHECKER_TEXTURE_TOKEN);
  830.       END_CASE
  831.  
  832.       CASE (MARBLE_TOKEN)
  833.          if (Texture->Constant_Flag) {
  834.             Texture = Copy_Texture (Texture);
  835.             Texture->Constant_Flag = FALSE;
  836.             }
  837.          Texture -> Texture_Number = MARBLE_TEXTURE;
  838.       END_CASE
  839.  
  840.       CASE (WOOD_TOKEN)
  841.          if (Texture->Constant_Flag) {
  842.             Texture = Copy_Texture (Texture);
  843.             Texture->Constant_Flag = FALSE;
  844.             }
  845.          Texture -> Texture_Number = WOOD_TEXTURE;
  846.       END_CASE
  847.  
  848.       CASE (SPOTTED_TOKEN)
  849.          if (Texture->Constant_Flag) {
  850.             Texture = Copy_Texture (Texture);
  851.             Texture->Constant_Flag = FALSE;
  852.             }
  853.          Texture -> Texture_Number = SPOTTED_TEXTURE;
  854.       END_CASE
  855.  
  856.       CASE (AGATE_TOKEN)
  857.          if (Texture->Constant_Flag) {
  858.             Texture = Copy_Texture (Texture);
  859.             Texture->Constant_Flag = FALSE;
  860.             }
  861.          Texture -> Texture_Number = AGATE_TEXTURE;
  862.       END_CASE
  863.  
  864.       CASE (GRANITE_TOKEN)
  865.          if (Texture->Constant_Flag) {
  866.             Texture = Copy_Texture (Texture);
  867.             Texture->Constant_Flag = FALSE;
  868.             }
  869.          Texture -> Texture_Number = GRANITE_TEXTURE;
  870.       END_CASE
  871.  
  872.        CASE (GRADIENT_TOKEN)
  873.          if (Texture->Constant_Flag) {
  874.             Texture = Copy_Texture (Texture);
  875.             Texture->Constant_Flag = FALSE;
  876.             }
  877.      Texture -> Texture_Number = GRADIENT_TEXTURE;
  878.      Parse_Vector (&(Texture -> Texture_Gradient));
  879.        END_CASE
  880.  
  881.       CASE (AMBIENT_TOKEN)
  882.          if (Texture->Constant_Flag) {
  883.             Texture = Copy_Texture (Texture);
  884.             Texture->Constant_Flag = FALSE;
  885.             }
  886.          (Texture -> Object_Ambient) = Parse_Float ();
  887.       END_CASE
  888.  
  889.       CASE (BRILLIANCE_TOKEN)
  890.          if (Texture->Constant_Flag) {
  891.             Texture = Copy_Texture (Texture);
  892.             Texture->Constant_Flag = FALSE;
  893.             }
  894.          (Texture -> Object_Brilliance) = Parse_Float ();
  895.       END_CASE
  896.  
  897.       CASE (ROUGHNESS_TOKEN)
  898.          if (Texture->Constant_Flag) {
  899.             Texture = Copy_Texture (Texture);
  900.             Texture->Constant_Flag = FALSE;
  901.             }
  902.          (Texture -> Object_Roughness) = Parse_Float ();
  903.          if (Texture -> Object_Roughness > 1.0)
  904.             Texture -> Object_Roughness = 1.0;
  905.          if (Texture -> Object_Roughness < 0.001)
  906.             Texture -> Object_Roughness = 0.001;
  907.       END_CASE
  908.  
  909.       CASE (PHONGSIZE_TOKEN)
  910.          if (Texture->Constant_Flag) {
  911.             Texture = Copy_Texture (Texture);
  912.             Texture->Constant_Flag = FALSE;
  913.             }
  914.          (Texture -> Object_PhongSize) = Parse_Float ();
  915.          if (Texture -> Object_PhongSize < 1.0)
  916.             Texture -> Object_PhongSize = 1.0;
  917.          if (Texture -> Object_PhongSize > 100)
  918.             Texture -> Object_PhongSize = 100;
  919.       END_CASE
  920.  
  921.       CASE (DIFFUSE_TOKEN)
  922.          if (Texture->Constant_Flag) {
  923.             Texture = Copy_Texture (Texture);
  924.             Texture->Constant_Flag = FALSE;
  925.             }
  926.          (Texture -> Object_Diffuse) = Parse_Float ();
  927.       END_CASE
  928.  
  929.       CASE (SPECULAR_TOKEN)
  930.          if (Texture->Constant_Flag) {
  931.             Texture = Copy_Texture (Texture);
  932.             Texture->Constant_Flag = FALSE;
  933.             }
  934.          (Texture -> Object_Specular) = Parse_Float ();
  935.       END_CASE
  936.  
  937.       CASE (PHONG_TOKEN)
  938.          if (Texture->Constant_Flag) {
  939.             Texture = Copy_Texture (Texture);
  940.             Texture->Constant_Flag = FALSE;
  941.             }
  942.          (Texture -> Object_Phong) = Parse_Float ();
  943.       END_CASE
  944.  
  945.       CASE (METALLIC_TOKEN)
  946.          if (Texture->Constant_Flag) {
  947.             Texture = Copy_Texture (Texture);
  948.             Texture->Constant_Flag = FALSE;
  949.             }
  950.          Texture -> Metallic_Flag = TRUE;
  951.       END_CASE
  952.  
  953.       CASE (IOR_TOKEN)
  954.          if (Texture->Constant_Flag) {
  955.             Texture = Copy_Texture (Texture);
  956.             Texture->Constant_Flag = FALSE;
  957.             }
  958.          (Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  959.       END_CASE
  960.  
  961.       CASE (REFRACTION_TOKEN)
  962.          if (Texture->Constant_Flag) {
  963.             Texture = Copy_Texture (Texture);
  964.             Texture->Constant_Flag = FALSE;
  965.             }
  966.          (Texture -> Object_Refraction) = Parse_Float ();
  967.       END_CASE
  968.  
  969.       CASE (REFLECTION_TOKEN)
  970.          if (Texture->Constant_Flag) {
  971.             Texture = Copy_Texture (Texture);
  972.             Texture->Constant_Flag = FALSE;
  973.             }
  974.          (Texture -> Object_Reflection) = Parse_Float ();
  975.       END_CASE
  976.  
  977.       CASE (IMAGEMAP_TOKEN)
  978.          if (Texture->Constant_Flag) {
  979.             Texture = Copy_Texture (Texture);
  980.             Texture->Constant_Flag = FALSE;
  981.             }
  982.          Texture -> Texture_Number = IMAGEMAP_TEXTURE;
  983.          if ((Texture->Image = (IMAGE *)malloc(sizeof(IMAGE))) == NULL)
  984.          Error("Cannot allocate imagemap texture");
  985.          Make_Vector (&Texture->Texture_Gradient, 1.0, -1.0, 0.0);
  986.          EXPECT
  987.             CASE (LEFT_ANGLE_TOKEN)
  988.                  UNGET
  989.                  Parse_Vector (&(Texture -> Texture_Gradient));
  990.             END_CASE
  991.  
  992.             CASE (IFF_TOKEN)
  993.                GET (STRING_TOKEN);
  994.                Read_Iff_Image(Texture->Image, Token.Token_String);
  995.                EXIT
  996.             END_CASE
  997.  
  998.             CASE (GIF_TOKEN)
  999.                GET (STRING_TOKEN);
  1000.                Read_Gif_Image(Texture->Image, Token.Token_String);
  1001.                EXIT
  1002.             END_CASE
  1003.  
  1004.             CASE (DUMP_TOKEN)
  1005.                GET (STRING_TOKEN);
  1006.                Read_Dump_Image(Texture->Image, Token.Token_String);
  1007.                EXIT
  1008.             END_CASE
  1009.  
  1010.             OTHERWISE
  1011.                Parse_Error (DUMP_TOKEN);
  1012.             END_CASE
  1013.          END_EXPECT
  1014.  
  1015.          EXPECT
  1016.             CASE (ALPHA_TOKEN)
  1017.                EXPECT
  1018.                   CASE (FLOAT_TOKEN)
  1019.                      reg = (int)(Token.Token_Float + 0.01);
  1020.                      if (Texture->Image->Colour_Map == NULL)
  1021.                         Error ("Can't apply ALPHA to a non colour-mapped image\n");
  1022.  
  1023.                      if ((reg < 0) || (reg >= Texture->Image->Colour_Map_Size))
  1024.                         Error ("ALPHA colour register value out of range.\n");
  1025.  
  1026.                      Texture->Image->Colour_Map[reg].Alpha = (unsigned short) (255.0 * Parse_Float());
  1027.                      EXIT
  1028.                   END_CASE
  1029.  
  1030.                   CASE (ALL_TOKEN)
  1031.                      {
  1032.                      DBL alpha;
  1033.                      alpha = Parse_Float();
  1034.  
  1035.                      for (reg = 0 ; reg < Texture->Image->Colour_Map_Size ; reg++)
  1036.                         Texture->Image->Colour_Map[reg].Alpha = (unsigned short) alpha;
  1037.                      }
  1038.                      EXIT
  1039.                   END_CASE
  1040.                END_EXPECT
  1041.             END_CASE
  1042.  
  1043.             OTHERWISE
  1044.                UNGET
  1045.                EXIT
  1046.             END_CASE
  1047.          END_EXPECT
  1048.       END_CASE
  1049.  
  1050.       CASE (WAVES_TOKEN)
  1051.          if (Texture->Constant_Flag) {
  1052.             Texture = Copy_Texture (Texture);
  1053.             Texture->Constant_Flag = FALSE;
  1054.             }
  1055.          Texture -> Bump_Number = WAVES;
  1056.          Texture -> Bump_Amount = Parse_Float ();
  1057.          EXPECT
  1058.             CASE (PHASE_TOKEN)
  1059.                Texture -> Phase = Parse_Float();
  1060.                EXIT
  1061.             END_CASE
  1062.  
  1063.             OTHERWISE
  1064.                UNGET
  1065.                EXIT
  1066.             END_CASE
  1067.          END_EXPECT
  1068.       END_CASE
  1069.  
  1070.       CASE (FREQUENCY_TOKEN)
  1071.          if (Texture->Constant_Flag) {
  1072.             Texture = Copy_Texture (Texture);
  1073.             Texture->Constant_Flag = FALSE;
  1074.             }
  1075.          Texture -> Frequency = Parse_Float();
  1076.       END_CASE
  1077.  
  1078.       CASE (PHASE_TOKEN)
  1079.          if (Texture->Constant_Flag) {
  1080.             Texture = Copy_Texture (Texture);
  1081.             Texture->Constant_Flag = FALSE;
  1082.             }
  1083.          Texture -> Phase = Parse_Float();
  1084.       END_CASE
  1085.  
  1086.       CASE (RIPPLES_TOKEN)
  1087.          if (Texture->Constant_Flag) {
  1088.             Texture = Copy_Texture (Texture);
  1089.             Texture->Constant_Flag = FALSE;
  1090.             }
  1091.          Texture -> Bump_Number = RIPPLES;
  1092.          Texture -> Bump_Amount = Parse_Float ();
  1093.       END_CASE
  1094.  
  1095.       CASE (WRINKLES_TOKEN)
  1096.          if (Texture->Constant_Flag) {
  1097.             Texture = Copy_Texture (Texture);
  1098.             Texture->Constant_Flag = FALSE;
  1099.             }
  1100.          Texture -> Bump_Number = WRINKLES;
  1101.          Texture -> Bump_Amount = Parse_Float ();
  1102.       END_CASE
  1103.  
  1104.       CASE (BUMPS_TOKEN)
  1105.          if (Texture->Constant_Flag) {
  1106.             Texture = Copy_Texture (Texture);
  1107.             Texture->Constant_Flag = FALSE;
  1108.             }
  1109.          Texture -> Bump_Number = BUMPS;
  1110.          Texture -> Bump_Amount = Parse_Float ();
  1111.       END_CASE
  1112.  
  1113.       CASE (DENTS_TOKEN)
  1114.          if (Texture->Constant_Flag) {
  1115.             Texture = Copy_Texture (Texture);
  1116.             Texture->Constant_Flag = FALSE;
  1117.             }
  1118.          Texture -> Bump_Number = DENTS;
  1119.          Texture -> Bump_Amount = Parse_Float ();
  1120.       END_CASE
  1121.  
  1122.       CASE (TRANSLATE_TOKEN)
  1123.          if (Texture->Constant_Flag) {
  1124.             Texture = Copy_Texture (Texture);
  1125.             Texture->Constant_Flag = FALSE;
  1126.             }
  1127.          Parse_Vector (&Local_Vector);
  1128.          if (!Texture -> Texture_Transformation)
  1129.             Texture -> Texture_Transformation = Get_Transformation ();
  1130.          Get_Translation_Transformation (&Local_Transformation,
  1131.                                          &Local_Vector);
  1132.          Compose_Transformations (Texture -> Texture_Transformation,
  1133.                                   &Local_Transformation);
  1134.       END_CASE
  1135.  
  1136.       CASE (ROTATE_TOKEN)
  1137.          if (Texture->Constant_Flag) {
  1138.             Texture = Copy_Texture (Texture);
  1139.             Texture->Constant_Flag = FALSE;
  1140.             }
  1141.          Parse_Vector (&Local_Vector);
  1142.          if (!Texture -> Texture_Transformation)
  1143.             Texture -> Texture_Transformation = Get_Transformation ();
  1144.          Get_Rotation_Transformation (&Local_Transformation,
  1145.                                       &Local_Vector);
  1146.          Compose_Transformations (Texture -> Texture_Transformation,
  1147.                                   &Local_Transformation);
  1148.       END_CASE
  1149.  
  1150.       CASE (SCALE_TOKEN)
  1151.          if (Texture->Constant_Flag) {
  1152.             Texture = Copy_Texture (Texture);
  1153.             Texture->Constant_Flag = FALSE;
  1154.             }
  1155.          Parse_Vector (&Local_Vector);
  1156.          if (!Texture -> Texture_Transformation)
  1157.              Texture -> Texture_Transformation = Get_Transformation ();
  1158.          Get_Scaling_Transformation (&Local_Transformation,
  1159.                                      &Local_Vector);
  1160.          Compose_Transformations (Texture -> Texture_Transformation,
  1161.                                   &Local_Transformation);
  1162.       END_CASE
  1163.  
  1164.       CASE (COLOUR_TOKEN)
  1165.          if (Texture->Constant_Flag) {
  1166.             Texture = Copy_Texture (Texture);
  1167.             Texture->Constant_Flag = FALSE;
  1168.             }
  1169.          Texture->Colour1 = Get_Colour();
  1170.          Parse_Colour (Texture -> Colour1);
  1171.          Texture -> Texture_Number = COLOUR_TEXTURE;
  1172.       END_CASE
  1173.  
  1174.       CASE (COLOUR_MAP_TOKEN)
  1175.          if (Texture->Constant_Flag) {
  1176.             Texture = Copy_Texture (Texture);
  1177.             Texture->Constant_Flag = FALSE;
  1178.             }
  1179.          Texture -> Colour_Map = Parse_Colour_Map();
  1180.       END_CASE
  1181.  
  1182.       CASE (END_TEXTURE_TOKEN)
  1183.          EXIT
  1184.       END_CASE
  1185.  
  1186.       OTHERWISE
  1187.          Parse_Error (END_TEXTURE_TOKEN);
  1188.       END_CASE
  1189.    END_EXPECT
  1190.    return (Texture);
  1191.    }
  1192.  
  1193. SHAPE *Parse_Sphere ()
  1194.   {
  1195.   SPHERE *Local_Shape;
  1196.   CONSTANT Constant_Id;
  1197.   VECTOR Local_Vector;
  1198.   TEXTURE *Local_Texture;
  1199.  
  1200.   Local_Shape = NULL;
  1201.  
  1202.   EXPECT
  1203.      CASE (LEFT_ANGLE_TOKEN)
  1204.        UNGET
  1205.        Local_Shape = Get_Sphere_Shape();
  1206.        Parse_Vector(&(Local_Shape -> Center));
  1207.        Local_Shape -> Radius = Parse_Float();
  1208.        Local_Shape -> Radius_Squared = Local_Shape -> Radius * Local_Shape -> Radius;
  1209.        Local_Shape -> Inverse_Radius = 1.0 / Local_Shape -> Radius;
  1210.        EXIT
  1211.      END_CASE
  1212.  
  1213.      CASE (IDENTIFIER_TOKEN)
  1214.        if ((Constant_Id = Find_Constant()) != -1)
  1215.          if (Constants[(int)Constant_Id].Constant_Type == SPHERE_CONSTANT)
  1216.            Local_Shape = (SPHERE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1217.          else
  1218.            Type_Error ();
  1219.        else
  1220.          Undeclared ();
  1221.        EXIT
  1222.      END_CASE
  1223.  
  1224.      OTHERWISE
  1225.         Parse_Error (LEFT_ANGLE_TOKEN);
  1226.      END_CASE
  1227.   END_EXPECT
  1228.  
  1229.   EXPECT
  1230.      CASE (END_SPHERE_TOKEN)
  1231.         EXIT
  1232.      END_CASE
  1233.  
  1234.      CASE (TRANSLATE_TOKEN)
  1235.         Parse_Vector (&Local_Vector);
  1236.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1237.      END_CASE
  1238.  
  1239.      CASE (ROTATE_TOKEN)
  1240.         Parse_Vector (&Local_Vector);
  1241.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1242.      END_CASE
  1243.  
  1244.      CASE (SCALE_TOKEN)
  1245.         Parse_Vector (&Local_Vector);
  1246.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1247.      END_CASE
  1248.  
  1249.      CASE (INVERSE_TOKEN)
  1250.         Invert ((OBJECT *) Local_Shape);
  1251.      END_CASE
  1252.  
  1253.      CASE (TEXTURE_TOKEN)
  1254.         Local_Texture = Parse_Texture ();
  1255.         if (Local_Texture->Constant_Flag)
  1256.            Local_Texture = Copy_Texture(Local_Texture);
  1257.  
  1258.         {
  1259.         TEXTURE *temp_texture;
  1260.  
  1261.         for (temp_texture = Local_Texture ;
  1262.              temp_texture->Next_Texture != NULL ;
  1263.              temp_texture = temp_texture->Next_Texture)
  1264.            {}
  1265.  
  1266.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1267.         Local_Shape->Shape_Texture = Local_Texture;
  1268.         }
  1269.      END_CASE
  1270.  
  1271.      CASE (COLOUR_TOKEN)
  1272.         Local_Shape->Shape_Colour = Get_Colour();
  1273.         Parse_Colour (Local_Shape->Shape_Colour);
  1274.      END_CASE
  1275.  
  1276.      OTHERWISE
  1277.         Parse_Error (END_SPHERE_TOKEN);
  1278.      END_CASE
  1279.   END_EXPECT
  1280.  
  1281.   return ((SHAPE *) Local_Shape);
  1282.   }
  1283.  
  1284. SHAPE *Parse_Plane ()
  1285.   {
  1286.   PLANE *Local_Shape;
  1287.   CONSTANT Constant_Id;
  1288.   VECTOR Local_Vector;
  1289.   TEXTURE *Local_Texture;
  1290.  
  1291.   Local_Shape = NULL;
  1292.  
  1293.   EXPECT
  1294.      CASE (LEFT_ANGLE_TOKEN)
  1295.        UNGET
  1296.        Local_Shape = Get_Plane_Shape();
  1297.        Parse_Vector(&(Local_Shape -> Normal_Vector));
  1298.        Local_Shape->Distance = Parse_Float();
  1299.        Local_Shape->Distance *= -1.0;
  1300.        EXIT
  1301.      END_CASE
  1302.  
  1303.      CASE (IDENTIFIER_TOKEN)
  1304.        if ((Constant_Id = Find_Constant()) != -1)
  1305.          if (Constants[(int)Constant_Id].Constant_Type == PLANE_CONSTANT)
  1306.            Local_Shape = (PLANE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1307.          else
  1308.            Type_Error ();
  1309.        else
  1310.          Undeclared ();
  1311.        EXIT
  1312.      END_CASE
  1313.  
  1314.      OTHERWISE
  1315.         Parse_Error (LEFT_ANGLE_TOKEN);
  1316.      END_CASE
  1317.   END_EXPECT
  1318.  
  1319.   EXPECT
  1320.      CASE (END_PLANE_TOKEN)
  1321.         EXIT
  1322.      END_CASE
  1323.  
  1324.      CASE (TRANSLATE_TOKEN)
  1325.         Parse_Vector (&Local_Vector);
  1326.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1327.      END_CASE
  1328.  
  1329.      CASE (ROTATE_TOKEN)
  1330.         Parse_Vector (&Local_Vector);
  1331.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1332.      END_CASE
  1333.  
  1334.      CASE (SCALE_TOKEN)
  1335.         Parse_Vector (&Local_Vector);
  1336.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1337.      END_CASE
  1338.  
  1339.      CASE (INVERSE_TOKEN)
  1340.         Invert ((OBJECT *) Local_Shape);
  1341.      END_CASE
  1342.  
  1343.      CASE (TEXTURE_TOKEN)
  1344.         Local_Texture = Parse_Texture ();
  1345.         if (Local_Texture->Constant_Flag)
  1346.            Local_Texture = Copy_Texture(Local_Texture);
  1347.  
  1348.         {
  1349.         TEXTURE *temp_texture;
  1350.  
  1351.         for (temp_texture = Local_Texture ;
  1352.              temp_texture->Next_Texture != NULL ;
  1353.              temp_texture = temp_texture->Next_Texture)
  1354.            {}
  1355.  
  1356.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1357.         Local_Shape->Shape_Texture = Local_Texture;
  1358.         }
  1359.      END_CASE
  1360.  
  1361.      CASE (COLOUR_TOKEN)
  1362.         Local_Shape->Shape_Colour = Get_Colour();
  1363.         Parse_Colour (Local_Shape->Shape_Colour);
  1364.      END_CASE
  1365.  
  1366.      OTHERWISE
  1367.         Parse_Error (END_PLANE_TOKEN);
  1368.      END_CASE
  1369.   END_EXPECT
  1370.  
  1371.   return ((SHAPE *) Local_Shape);
  1372.   }
  1373.  
  1374. SHAPE *Parse_Triangle ()
  1375.   {
  1376.   TRIANGLE *Local_Shape;
  1377.   CONSTANT Constant_Id;
  1378.   VECTOR Local_Vector;
  1379.   TEXTURE *Local_Texture;
  1380.  
  1381.   Local_Shape = NULL;
  1382.  
  1383.   EXPECT
  1384.      CASE (LEFT_ANGLE_TOKEN)
  1385.        UNGET
  1386.        Local_Shape = Get_Triangle_Shape();
  1387.        Parse_Vector (&Local_Shape->P1);
  1388.        Parse_Vector (&Local_Shape->P2);
  1389.        Parse_Vector (&Local_Shape->P3);
  1390.        if (!Compute_Triangle (Local_Shape)) {
  1391.           fprintf (stderr, "Degenerate triangle on line %d.  Please remove.\n",
  1392.                   Token.Token_Line_No);
  1393.           Degenerate_Triangles = TRUE;
  1394.           }
  1395.        EXIT
  1396.      END_CASE
  1397.  
  1398.      CASE (IDENTIFIER_TOKEN)
  1399.        if ((Constant_Id = Find_Constant()) != -1)
  1400.          if (Constants[(int)Constant_Id].Constant_Type == TRIANGLE_CONSTANT)
  1401.            Local_Shape = (TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1402.          else
  1403.            Type_Error ();
  1404.        else
  1405.          Undeclared ();
  1406.        EXIT
  1407.      END_CASE
  1408.  
  1409.      OTHERWISE
  1410.         Parse_Error (LEFT_ANGLE_TOKEN);
  1411.      END_CASE
  1412.   END_EXPECT
  1413.  
  1414.   EXPECT
  1415.      CASE (END_TRIANGLE_TOKEN)
  1416.         EXIT
  1417.      END_CASE
  1418.  
  1419.      CASE (TRANSLATE_TOKEN)
  1420.         Parse_Vector (&Local_Vector);
  1421.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1422.      END_CASE
  1423.  
  1424.      CASE (ROTATE_TOKEN)
  1425.         Parse_Vector (&Local_Vector);
  1426.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1427.      END_CASE
  1428.  
  1429.      CASE (SCALE_TOKEN)
  1430.         Parse_Vector (&Local_Vector);
  1431.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1432.      END_CASE
  1433.  
  1434.      CASE (INVERSE_TOKEN)
  1435.         Invert ((OBJECT *) Local_Shape);
  1436.      END_CASE
  1437.  
  1438.      CASE (TEXTURE_TOKEN)
  1439.         Local_Texture = Parse_Texture ();
  1440.         if (Local_Texture->Constant_Flag)
  1441.            Local_Texture = Copy_Texture(Local_Texture);
  1442.  
  1443.         {
  1444.         TEXTURE *temp_texture;
  1445.  
  1446.         for (temp_texture = Local_Texture ;
  1447.              temp_texture->Next_Texture != NULL ;
  1448.              temp_texture = temp_texture->Next_Texture)
  1449.            {}
  1450.  
  1451.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1452.         Local_Shape->Shape_Texture = Local_Texture;
  1453.         }
  1454.      END_CASE
  1455.  
  1456.      CASE (COLOUR_TOKEN)
  1457.         Local_Shape->Shape_Colour = Get_Colour();
  1458.         Parse_Colour (Local_Shape->Shape_Colour);
  1459.      END_CASE
  1460.  
  1461.      OTHERWISE
  1462.         Parse_Error (END_TRIANGLE_TOKEN);
  1463.      END_CASE
  1464.   END_EXPECT
  1465.  
  1466.   return ((SHAPE *) Local_Shape);
  1467.   }
  1468.  
  1469. SHAPE *Parse_Smooth_Triangle ()
  1470.   {
  1471.   SMOOTH_TRIANGLE *Local_Shape;
  1472.   CONSTANT Constant_Id;
  1473.   VECTOR Local_Vector;
  1474.   TEXTURE *Local_Texture;
  1475.  
  1476.   Local_Shape = NULL;
  1477.  
  1478.   EXPECT
  1479.      CASE (LEFT_ANGLE_TOKEN)
  1480.        UNGET
  1481.        Local_Shape = (SMOOTH_TRIANGLE *) Get_Smooth_Triangle_Shape();
  1482.        Parse_Vector (&Local_Shape->P1);
  1483.        Parse_Vector (&Local_Shape->N1);
  1484.        VNormalize (Local_Shape->N1, Local_Shape->N1)
  1485.        Parse_Vector (&Local_Shape->P2);
  1486.        Parse_Vector (&Local_Shape->N2);
  1487.        VNormalize (Local_Shape->N2, Local_Shape->N2)
  1488.        Parse_Vector (&Local_Shape->P3);
  1489.        Parse_Vector (&Local_Shape->N3);
  1490.        VNormalize (Local_Shape->N3, Local_Shape->N3)
  1491.        if (!Compute_Triangle ((TRIANGLE *) Local_Shape)) {
  1492.           fprintf (stderr, "Degenerate triangle on line %d.  Please remove.\n",
  1493.                   Token.Token_Line_No);
  1494.           Degenerate_Triangles = TRUE;
  1495.           }
  1496.        EXIT
  1497.      END_CASE
  1498.  
  1499.      CASE (IDENTIFIER_TOKEN)
  1500.        if ((Constant_Id = Find_Constant()) != -1)
  1501.          if (Constants[(int)Constant_Id].Constant_Type == SMOOTH_TRIANGLE_CONSTANT)
  1502.            Local_Shape = (SMOOTH_TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1503.          else
  1504.            Type_Error ();
  1505.        else
  1506.          Undeclared ();
  1507.        EXIT
  1508.      END_CASE
  1509.  
  1510.      OTHERWISE
  1511.         Parse_Error (LEFT_ANGLE_TOKEN);
  1512.      END_CASE
  1513.   END_EXPECT
  1514.  
  1515.   EXPECT
  1516.      CASE2 (END_TRIANGLE_TOKEN, END_SMOOTH_TRIANGLE_TOKEN)
  1517.         EXIT
  1518.      END_CASE
  1519.  
  1520.      CASE (TRANSLATE_TOKEN)
  1521.         Parse_Vector (&Local_Vector);
  1522.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1523.      END_CASE
  1524.  
  1525.      CASE (ROTATE_TOKEN)
  1526.         Parse_Vector (&Local_Vector);
  1527.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1528.      END_CASE
  1529.  
  1530.      CASE (SCALE_TOKEN)
  1531.         Parse_Vector (&Local_Vector);
  1532.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1533.      END_CASE
  1534.  
  1535.      CASE (INVERSE_TOKEN)
  1536.         Invert ((OBJECT *) Local_Shape);
  1537.      END_CASE
  1538.  
  1539.      CASE (TEXTURE_TOKEN)
  1540.         Local_Texture = Parse_Texture ();
  1541.         if (Local_Texture->Constant_Flag)
  1542.            Local_Texture = Copy_Texture(Local_Texture);
  1543.  
  1544.         {
  1545.         TEXTURE *temp_texture;
  1546.  
  1547.         for (temp_texture = Local_Texture ;
  1548.              temp_texture->Next_Texture != NULL ;
  1549.              temp_texture = temp_texture->Next_Texture)
  1550.            {}
  1551.  
  1552.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1553.         Local_Shape->Shape_Texture = Local_Texture;
  1554.         }
  1555.      END_CASE
  1556.  
  1557.      CASE (COLOUR_TOKEN)
  1558.         Local_Shape->Shape_Colour = Get_Colour();
  1559.         Parse_Colour (Local_Shape->Shape_Colour);
  1560.      END_CASE
  1561.  
  1562.      OTHERWISE
  1563.         Parse_Error (END_SMOOTH_TRIANGLE_TOKEN);
  1564.      END_CASE
  1565.   END_EXPECT
  1566.  
  1567.   return ((SHAPE *) Local_Shape);
  1568.   }
  1569.  
  1570. SHAPE *Parse_Quadric ()
  1571.   {
  1572.   QUADRIC *Local_Shape;
  1573.   VECTOR Local_Vector;
  1574.   CONSTANT Constant_Id;
  1575.   TEXTURE *Local_Texture;
  1576.  
  1577.   Local_Shape = NULL;
  1578.  
  1579.   EXPECT
  1580.      CASE (LEFT_ANGLE_TOKEN)
  1581.        UNGET
  1582.        Local_Shape = Get_Quadric_Shape();
  1583.        Parse_Vector(&(Local_Shape -> Object_2_Terms));
  1584.        Parse_Vector(&(Local_Shape -> Object_Mixed_Terms));
  1585.        Parse_Vector(&(Local_Shape -> Object_Terms));
  1586.        (Local_Shape -> Object_Constant) = Parse_Float();
  1587.        Local_Shape -> Non_Zero_Square_Term = 
  1588.          !((Local_Shape -> Object_2_Terms.x == 0.0)
  1589.           && (Local_Shape -> Object_2_Terms.y == 0.0)
  1590.           && (Local_Shape -> Object_2_Terms.z == 0.0)
  1591.           && (Local_Shape -> Object_Mixed_Terms.x == 0.0)
  1592.           && (Local_Shape -> Object_Mixed_Terms.y == 0.0)
  1593.           && (Local_Shape -> Object_Mixed_Terms.z == 0.0));
  1594.        EXIT
  1595.      END_CASE
  1596.  
  1597.      CASE (IDENTIFIER_TOKEN)
  1598.        if ((Constant_Id = Find_Constant()) != -1)
  1599.          if (Constants[(int)Constant_Id].Constant_Type == QUADRIC_CONSTANT)
  1600.            Local_Shape = (QUADRIC *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1601.          else
  1602.            Type_Error ();
  1603.        else
  1604.          Undeclared ();
  1605.        EXIT
  1606.      END_CASE
  1607.  
  1608.      OTHERWISE
  1609.         Parse_Error (LEFT_ANGLE_TOKEN);
  1610.      END_CASE
  1611.   END_EXPECT
  1612.  
  1613.   EXPECT
  1614.      CASE (END_QUADRIC_TOKEN)
  1615.         EXIT
  1616.      END_CASE
  1617.  
  1618.      CASE (TRANSLATE_TOKEN)
  1619.         Parse_Vector (&Local_Vector);
  1620.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1621.      END_CASE
  1622.  
  1623.      CASE (ROTATE_TOKEN)
  1624.         Parse_Vector (&Local_Vector);
  1625.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1626.      END_CASE
  1627.  
  1628.      CASE (SCALE_TOKEN)
  1629.         Parse_Vector (&Local_Vector);
  1630.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1631.      END_CASE
  1632.  
  1633.      CASE (INVERSE_TOKEN)
  1634.         Invert ((OBJECT *) Local_Shape);
  1635.      END_CASE
  1636.  
  1637.      CASE (TEXTURE_TOKEN)
  1638.         Local_Texture = Parse_Texture ();
  1639.         if (Local_Texture->Constant_Flag)
  1640.            Local_Texture = Copy_Texture(Local_Texture);
  1641.  
  1642.         {
  1643.         TEXTURE *temp_texture;
  1644.  
  1645.         for (temp_texture = Local_Texture ;
  1646.              temp_texture->Next_Texture != NULL ;
  1647.              temp_texture = temp_texture->Next_Texture)
  1648.            {}
  1649.  
  1650.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1651.         Local_Shape->Shape_Texture = Local_Texture;
  1652.         }
  1653.      END_CASE
  1654.  
  1655.      CASE (COLOUR_TOKEN)
  1656.         Local_Shape->Shape_Colour = Get_Colour();
  1657.         Parse_Colour (Local_Shape->Shape_Colour);
  1658.      END_CASE
  1659.  
  1660.      OTHERWISE
  1661.         Parse_Error (END_QUADRIC_TOKEN);
  1662.      END_CASE
  1663.   END_EXPECT
  1664.  
  1665.   return ((SHAPE *) Local_Shape);
  1666.   }
  1667.  
  1668. SHAPE *Parse_Quartic ()
  1669. {
  1670.   QUARTIC *Local_Shape;
  1671.   VECTOR Local_Vector;
  1672.   CONSTANT Constant_Id;
  1673.   TEXTURE *Local_Texture;
  1674.  
  1675.   Local_Shape = NULL;
  1676.  
  1677.   EXPECT
  1678.      CASE (LEFT_ANGLE_TOKEN)
  1679.        UNGET
  1680.        Local_Shape = Get_Quartic_Shape();
  1681.        Parse_Coeffs(&(Local_Shape->Coeffs[0]));
  1682.        EXIT
  1683.      END_CASE
  1684.  
  1685.      CASE (IDENTIFIER_TOKEN)
  1686.        if ((Constant_Id = Find_Constant()) != -1)
  1687.          if (Constants[(int)Constant_Id].Constant_Type == QUARTIC_CONSTANT)
  1688.            Local_Shape = (QUARTIC *)Copy((OBJECT *)
  1689.                         Constants[(int)Constant_Id].Constant_Data);
  1690.          else
  1691.            Type_Error ();
  1692.        else
  1693.          Undeclared ();
  1694.        EXIT
  1695.      END_CASE
  1696.  
  1697.      OTHERWISE
  1698.         Parse_Error (LEFT_ANGLE_TOKEN);
  1699.      END_CASE
  1700.   END_EXPECT
  1701.  
  1702.   EXPECT
  1703.      CASE (END_QUARTIC_TOKEN)
  1704.         EXIT
  1705.      END_CASE
  1706.  
  1707.      CASE (TRANSLATE_TOKEN)
  1708.         Parse_Vector (&Local_Vector);
  1709.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1710.      END_CASE
  1711.  
  1712.      CASE (ROTATE_TOKEN)
  1713.         Parse_Vector (&Local_Vector);
  1714.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1715.      END_CASE
  1716.  
  1717.      CASE (SCALE_TOKEN)
  1718.         Parse_Vector (&Local_Vector);
  1719.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1720.      END_CASE
  1721.  
  1722.      CASE (INVERSE_TOKEN)
  1723.         Invert ((OBJECT *) Local_Shape);
  1724.      END_CASE
  1725.  
  1726.      CASE (TEXTURE_TOKEN)
  1727.         Local_Texture = Parse_Texture ();
  1728.         if (Local_Texture->Constant_Flag)
  1729.            Local_Texture = Copy_Texture(Local_Texture);
  1730.  
  1731.         {
  1732.         TEXTURE *temp_texture;
  1733.  
  1734.         for (temp_texture = Local_Texture ;
  1735.              temp_texture->Next_Texture != NULL ;
  1736.              temp_texture = temp_texture->Next_Texture)
  1737.            {}
  1738.  
  1739.         temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1740.         Local_Shape->Shape_Texture = Local_Texture;
  1741.         }
  1742.      END_CASE
  1743.  
  1744.      CASE (COLOUR_TOKEN)
  1745.         Local_Shape->Shape_Colour = Get_Colour();
  1746.         Parse_Colour (Local_Shape->Shape_Colour);
  1747.      END_CASE
  1748.  
  1749.      OTHERWISE
  1750.         Parse_Error (END_QUARTIC_TOKEN);
  1751.      END_CASE
  1752.   END_EXPECT
  1753.   return ((SHAPE *) Local_Shape);
  1754. }
  1755.  
  1756. CSG_SHAPE *Parse_CSG (type, Parent_Object)
  1757.   int type;
  1758.   OBJECT *Parent_Object;
  1759.   {
  1760.   CSG_SHAPE *Container = NULL;
  1761.   SHAPE *Local_Shape;
  1762.   VECTOR Local_Vector;
  1763.   CONSTANT Constant_Id;
  1764.   int First_Shape_Parsed = FALSE;
  1765.  
  1766.   if (type == CSG_UNION_TYPE)
  1767.     Container = Get_CSG_Union ();
  1768.  
  1769.   else if ((type == CSG_INTERSECTION_TYPE) || (type == CSG_DIFFERENCE_TYPE))
  1770.     Container = Get_CSG_Intersection ();
  1771.  
  1772.   Container -> Parent_Object = Parent_Object;
  1773.  
  1774.   EXPECT
  1775.      CASE (IDENTIFIER_TOKEN)
  1776.        if ((Constant_Id = Find_Constant()) != -1)
  1777.          if ((Constants[(int)Constant_Id].Constant_Type == CSG_INTERSECTION_CONSTANT)
  1778.              || (Constants[(int)Constant_Id].Constant_Type == CSG_UNION_CONSTANT)
  1779.              || (Constants[(int)Constant_Id].Constant_Type == CSG_DIFFERENCE_CONSTANT)) {
  1780.            free (Container);
  1781.            Container = (CSG_SHAPE *) Copy ((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1782.            Set_CSG_Parents(Container, Parent_Object);
  1783.            }
  1784.          else
  1785.            Type_Error ();
  1786.        else
  1787.          Undeclared ();
  1788.      END_CASE
  1789.  
  1790.      CASE (SPHERE_TOKEN)
  1791.        Local_Shape = Parse_Sphere ();
  1792.        Local_Shape -> Parent_Object = Parent_Object;
  1793.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1794.           Invert ((OBJECT *) Local_Shape);
  1795.        First_Shape_Parsed = TRUE;
  1796.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1797.                (OBJECT **) &(Container -> Shapes));
  1798.      END_CASE
  1799.  
  1800.      CASE (PLANE_TOKEN)
  1801.        Local_Shape = Parse_Plane ();
  1802.        Local_Shape -> Parent_Object = Parent_Object;
  1803.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1804.           Invert ((OBJECT *) Local_Shape);
  1805.        First_Shape_Parsed = TRUE;
  1806.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1807.                (OBJECT **) &(Container -> Shapes));
  1808.      END_CASE
  1809.  
  1810.      CASE (TRIANGLE_TOKEN)
  1811.        Local_Shape = Parse_Triangle ();
  1812.        Local_Shape -> Parent_Object = Parent_Object;
  1813.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1814.           Invert ((OBJECT *) Local_Shape);
  1815.        First_Shape_Parsed = TRUE;
  1816.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1817.                (OBJECT **) &(Container -> Shapes));
  1818.      END_CASE
  1819.  
  1820.      CASE (SMOOTH_TRIANGLE_TOKEN)
  1821.        Local_Shape = Parse_Smooth_Triangle ();
  1822.        Local_Shape -> Parent_Object = Parent_Object;
  1823.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1824.           Invert ((OBJECT *) Local_Shape);
  1825.        First_Shape_Parsed = TRUE;
  1826.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1827.                (OBJECT **) &(Container -> Shapes));
  1828.      END_CASE
  1829.  
  1830.      CASE (QUADRIC_TOKEN)
  1831.        Local_Shape = Parse_Quadric ();
  1832.        Local_Shape -> Parent_Object = Parent_Object;
  1833.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1834.           Invert ((OBJECT *) Local_Shape);
  1835.        First_Shape_Parsed = TRUE;
  1836.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1837.                (OBJECT **) &(Container -> Shapes));
  1838.      END_CASE
  1839.  
  1840.      CASE (QUARTIC_TOKEN)
  1841.        Local_Shape = Parse_Quartic ();
  1842.        Local_Shape -> Parent_Object = Parent_Object;
  1843.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1844.           Invert ((OBJECT *) Local_Shape);
  1845.        First_Shape_Parsed = TRUE;
  1846.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1847.                (OBJECT **) &(Container -> Shapes));
  1848.      END_CASE
  1849.  
  1850.      CASE (UNION_TOKEN)
  1851.        Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Parent_Object);
  1852.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1853.           Invert ((OBJECT *) Local_Shape);
  1854.        First_Shape_Parsed = TRUE;
  1855.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1856.                (OBJECT **) &(Container -> Shapes));
  1857.      END_CASE
  1858.  
  1859.      CASE (INTERSECTION_TOKEN)
  1860.        Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Parent_Object);
  1861.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1862.           Invert ((OBJECT *) Local_Shape);
  1863.        First_Shape_Parsed = TRUE;
  1864.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1865.                (OBJECT **) &(Container -> Shapes));
  1866.      END_CASE
  1867.  
  1868.      CASE (DIFFERENCE_TOKEN)
  1869.        Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Parent_Object);
  1870.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1871.           Invert ((OBJECT *) Local_Shape);
  1872.        First_Shape_Parsed = TRUE;
  1873.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1874.                (OBJECT **) &(Container -> Shapes));
  1875.      END_CASE
  1876.  
  1877.      OTHERWISE
  1878.         UNGET
  1879.         EXIT
  1880.      END_CASE
  1881.   END_EXPECT
  1882.  
  1883.   EXPECT
  1884.      CASE3 (END_UNION_TOKEN, END_INTERSECTION_TOKEN, END_DIFFERENCE_TOKEN)
  1885.         EXIT
  1886.      END_CASE
  1887.  
  1888.      CASE (TRANSLATE_TOKEN)
  1889.         Parse_Vector (&Local_Vector);
  1890.         Translate((OBJECT *) Container, &Local_Vector);
  1891.      END_CASE
  1892.  
  1893.      CASE (ROTATE_TOKEN)
  1894.         Parse_Vector (&Local_Vector);
  1895.         Rotate ((OBJECT *) Container, &Local_Vector);
  1896.      END_CASE
  1897.  
  1898.      CASE (SCALE_TOKEN)
  1899.         Parse_Vector (&Local_Vector);
  1900.         Scale ((OBJECT *) Container, &Local_Vector);
  1901.      END_CASE
  1902.  
  1903.      CASE (INVERSE_TOKEN)
  1904.         Invert ((OBJECT *) Container);
  1905.      END_CASE
  1906.  
  1907.      OTHERWISE
  1908.         if (type == CSG_UNION_TYPE)
  1909.            Parse_Error (END_UNION_TOKEN);
  1910.         else if (type == CSG_INTERSECTION_TYPE)
  1911.            Parse_Error (END_INTERSECTION_TOKEN);
  1912.         else
  1913.            Parse_Error (END_DIFFERENCE_TOKEN);
  1914.      END_CASE
  1915.   END_EXPECT
  1916.  
  1917.   return ((CSG_SHAPE *) Container);
  1918.   }
  1919.  
  1920. SHAPE *Parse_Shape (Object)
  1921.   OBJECT *Object;
  1922.   {
  1923.   SHAPE *Local_Shape = NULL;
  1924.  
  1925.   EXPECT
  1926.     CASE (SPHERE_TOKEN)
  1927.       Local_Shape = Parse_Sphere ();
  1928.       Local_Shape -> Parent_Object = Object;
  1929.       EXIT
  1930.     END_CASE
  1931.  
  1932.     CASE (PLANE_TOKEN)
  1933.       Local_Shape = Parse_Plane ();
  1934.       Local_Shape -> Parent_Object = Object;
  1935.       EXIT
  1936.     END_CASE
  1937.  
  1938.     CASE (TRIANGLE_TOKEN)
  1939.       Local_Shape = Parse_Triangle ();
  1940.       Local_Shape -> Parent_Object = Object;
  1941.       EXIT
  1942.     END_CASE
  1943.  
  1944.     CASE (SMOOTH_TRIANGLE_TOKEN)
  1945.       Local_Shape = Parse_Smooth_Triangle ();
  1946.       Local_Shape -> Parent_Object = Object;
  1947.       EXIT
  1948.     END_CASE
  1949.  
  1950.     CASE (QUADRIC_TOKEN)
  1951.       Local_Shape = Parse_Quadric ();
  1952.       Local_Shape -> Parent_Object = Object;
  1953.       EXIT
  1954.     END_CASE
  1955.  
  1956.     CASE (QUARTIC_TOKEN)
  1957.       Local_Shape = Parse_Quartic ();
  1958.       Local_Shape -> Parent_Object = Object;
  1959.       EXIT
  1960.     END_CASE
  1961.  
  1962.     CASE (UNION_TOKEN)
  1963.       Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Object);
  1964.       EXIT
  1965.     END_CASE
  1966.  
  1967.     CASE (INTERSECTION_TOKEN)
  1968.       Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Object);
  1969.       EXIT
  1970.     END_CASE
  1971.  
  1972.     CASE (DIFFERENCE_TOKEN)
  1973.       Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Object);
  1974.       EXIT
  1975.     END_CASE
  1976.  
  1977.     OTHERWISE
  1978.        Parse_Error (QUADRIC_TOKEN);
  1979.     END_CASE
  1980.   END_EXPECT
  1981.   return (Local_Shape);
  1982.   }
  1983.  
  1984. OBJECT *Parse_Object ()
  1985.   {
  1986.   OBJECT *Object;
  1987.   SHAPE *Local_Shape;
  1988.   VECTOR Local_Vector;
  1989.   CONSTANT Constant_Id;
  1990.   TEXTURE *Local_Texture;
  1991.  
  1992.   Object = NULL;
  1993.  
  1994.   EXPECT
  1995.     CASE (IDENTIFIER_TOKEN)
  1996.       if ((Constant_Id = Find_Constant()) != -1)
  1997.         if (Constants[(int)Constant_Id].Constant_Type == OBJECT_CONSTANT)
  1998.           Object = (OBJECT *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1999.         else
  2000.           Type_Error ();
  2001.       else
  2002.         Undeclared ();
  2003.       EXIT
  2004.     END_CASE
  2005.  
  2006.     CASE6 (SPHERE_TOKEN, QUADRIC_TOKEN, QUARTIC_TOKEN, UNION_TOKEN,
  2007.            INTERSECTION_TOKEN, DIFFERENCE_TOKEN)
  2008.     CASE3 (TRIANGLE_TOKEN, SMOOTH_TRIANGLE_TOKEN, PLANE_TOKEN)
  2009.         UNGET
  2010.         if (Object == NULL)
  2011.            Object = Get_Object();
  2012.  
  2013.         Local_Shape = Parse_Shape(Object);
  2014.         Link((OBJECT *)Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2015.                 (OBJECT **) &(Object -> Shape));
  2016.         EXIT
  2017.     END_CASE
  2018.  
  2019.     OTHERWISE
  2020.         Parse_Error (QUADRIC_TOKEN);
  2021.         EXIT
  2022.     END_CASE
  2023.   END_EXPECT
  2024.  
  2025.   EXPECT
  2026.     CASE (BOUNDED_TOKEN)
  2027.        EXPECT
  2028.           CASE (END_BOUNDED_TOKEN)
  2029.              EXIT
  2030.           END_CASE
  2031.  
  2032.           OTHERWISE
  2033.              UNGET
  2034.              Local_Shape = Parse_Shape(Object);
  2035.              Link((OBJECT *) Local_Shape,
  2036.                   (OBJECT **) &(Local_Shape -> Next_Object),
  2037.                   (OBJECT **) &(Object -> Bounding_Shapes));
  2038.           END_CASE
  2039.        END_EXPECT       
  2040.     END_CASE
  2041.  
  2042.     CASE (COLOUR_TOKEN)
  2043.        Object->Object_Colour = Get_Colour();
  2044.        Parse_Colour (Object -> Object_Colour);
  2045.     END_CASE
  2046.  
  2047.     CASE (TEXTURE_TOKEN)
  2048.         Local_Texture = Parse_Texture ();
  2049.         if (Local_Texture->Constant_Flag)
  2050.            Local_Texture = Copy_Texture(Local_Texture);
  2051.  
  2052.         if (Object->Object_Texture == Default_Texture)
  2053.            Object->Object_Texture = Local_Texture;
  2054.         else
  2055.         {
  2056.         TEXTURE *temp_texture;
  2057.  
  2058.         for (temp_texture = Local_Texture ;
  2059.              temp_texture->Next_Texture != NULL ;
  2060.              temp_texture = temp_texture->Next_Texture)
  2061.            {}
  2062.  
  2063.         temp_texture->Next_Texture = Object->Object_Texture;
  2064.         Object->Object_Texture = Local_Texture;
  2065.         }
  2066.     END_CASE
  2067.  
  2068.     CASE (LIGHT_SOURCE_TOKEN)
  2069.       Object -> Light_Source_Flag = TRUE;
  2070.     END_CASE
  2071.  
  2072.     CASE (TRANSLATE_TOKEN)
  2073.        Parse_Vector (&Local_Vector);
  2074.        Translate (Object, &Local_Vector);
  2075.     END_CASE
  2076.  
  2077.     CASE (ROTATE_TOKEN)
  2078.        Parse_Vector (&Local_Vector);
  2079.        Rotate (Object, &Local_Vector);
  2080.     END_CASE
  2081.  
  2082.     CASE (SCALE_TOKEN)
  2083.        Parse_Vector (&Local_Vector);
  2084.        Scale (Object, &Local_Vector);
  2085.     END_CASE
  2086.  
  2087.     CASE (INVERSE_TOKEN)
  2088.        Invert (Object);
  2089.     END_CASE
  2090.  
  2091.     CASE (END_OBJECT_TOKEN)
  2092.       EXIT
  2093.     END_CASE
  2094.  
  2095.     OTHERWISE
  2096.       Parse_Error (END_OBJECT_TOKEN);
  2097.     END_CASE
  2098.  
  2099.   END_EXPECT
  2100.  
  2101.   return (Object);
  2102.   }
  2103.  
  2104. OBJECT *Parse_Composite ()
  2105.   {
  2106.   COMPOSITE *Local_Composite;
  2107.   OBJECT *Local_Object;
  2108.   SHAPE *Local_Shape;
  2109.   CONSTANT Constant_Id;
  2110.   VECTOR Local_Vector;
  2111.  
  2112.   Local_Composite = NULL;
  2113.  
  2114.   EXPECT
  2115.     CASE (IDENTIFIER_TOKEN)
  2116.       if ((Constant_Id = Find_Constant()) != -1)
  2117.         if (Constants[(int)Constant_Id].Constant_Type == COMPOSITE_CONSTANT)
  2118.           Local_Composite = (COMPOSITE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2119.         else          
  2120.           Type_Error ();
  2121.       else
  2122.         Undeclared ();
  2123.     END_CASE
  2124.  
  2125.     CASE (COMPOSITE_TOKEN)
  2126.       if (Local_Composite == NULL)       
  2127.            Local_Composite = Get_Composite_Object();
  2128.  
  2129.       Local_Object = Parse_Composite();
  2130.       Link((OBJECT *) Local_Object,(OBJECT **) &(Local_Object -> Next_Object),
  2131.               (OBJECT **) &(Local_Composite -> Objects));
  2132.     END_CASE
  2133.  
  2134.     CASE (OBJECT_TOKEN)
  2135.       if (Local_Composite == NULL)       
  2136.            Local_Composite = Get_Composite_Object();
  2137.  
  2138.       Local_Object = Parse_Object();
  2139.       Link(Local_Object, &(Local_Object -> Next_Object),
  2140.                &(Local_Composite -> Objects));
  2141.     END_CASE
  2142.  
  2143.     CASE (END_COMPOSITE_TOKEN)
  2144.       UNGET
  2145.       if (Local_Composite == NULL)       
  2146.         Local_Composite = Get_Composite_Object();
  2147.  
  2148.       EXIT
  2149.     END_CASE
  2150.  
  2151.     OTHERWISE
  2152.        UNGET
  2153.        EXIT
  2154.     END_CASE
  2155.   END_EXPECT
  2156.  
  2157.   EXPECT
  2158.     CASE (END_COMPOSITE_TOKEN)
  2159.        EXIT
  2160.     END_CASE
  2161.  
  2162.     CASE (BOUNDED_TOKEN)
  2163.        EXPECT
  2164.           CASE (END_BOUNDED_TOKEN)
  2165.              EXIT
  2166.           END_CASE
  2167.  
  2168.           OTHERWISE
  2169.              UNGET
  2170.              Local_Shape = Parse_Shape((OBJECT *) Local_Composite);
  2171.              Link((OBJECT *) Local_Shape,
  2172.                   (OBJECT **) &(Local_Shape -> Next_Object),
  2173.                   (OBJECT **) &(Local_Composite -> Bounding_Shapes));
  2174.           END_CASE
  2175.        END_EXPECT       
  2176.     END_CASE
  2177.  
  2178.     CASE (TRANSLATE_TOKEN)
  2179.        Parse_Vector (&Local_Vector);
  2180.        Translate ((OBJECT *) Local_Composite, &Local_Vector);
  2181.     END_CASE
  2182.  
  2183.     CASE (ROTATE_TOKEN)
  2184.        Parse_Vector (&Local_Vector);
  2185.        Rotate ((OBJECT *) Local_Composite, &Local_Vector);
  2186.     END_CASE
  2187.  
  2188.     CASE (SCALE_TOKEN)
  2189.        Parse_Vector (&Local_Vector);
  2190.        Scale ((OBJECT *) Local_Composite, &Local_Vector);
  2191.     END_CASE
  2192.  
  2193.      CASE (INVERSE_TOKEN)
  2194.         Invert ((OBJECT *) Local_Composite);
  2195.      END_CASE
  2196.  
  2197.     OTHERWISE
  2198.        Parse_Error (END_COMPOSITE_TOKEN);
  2199.     END_CASE
  2200.   END_EXPECT
  2201.  
  2202.   return ((OBJECT *) Local_Composite);
  2203.   }
  2204.  
  2205. void Parse_Fog ()
  2206.    {
  2207.    EXPECT
  2208.       CASE (COLOUR_TOKEN)
  2209.          Parse_Colour (&Parsing_Frame_Ptr->Fog_Colour);
  2210.       END_CASE
  2211.  
  2212.       CASE (FLOAT_TOKEN)
  2213.          Parsing_Frame_Ptr->Fog_Distance = Token.Token_Float;
  2214.       END_CASE
  2215.  
  2216.       CASE (END_FOG_TOKEN)
  2217.          EXIT
  2218.       END_CASE
  2219.  
  2220.       OTHERWISE
  2221.          Parse_Error (END_FOG_TOKEN);
  2222.       END_CASE
  2223.    END_EXPECT
  2224.    }
  2225.  
  2226. void Add_Composite_Light_Source (Object)
  2227.    COMPOSITE *Object;
  2228.    {
  2229.    OBJECT *Temp_Object;
  2230.  
  2231.    for (Temp_Object = Object -> Objects;
  2232.         Temp_Object != NULL ; 
  2233.         Temp_Object = Temp_Object->Next_Object) {
  2234.  
  2235.       if (Temp_Object->Type == OBJECT_TYPE) {
  2236.          if (Temp_Object->Light_Source_Flag) {
  2237.             Link(Temp_Object, &(Temp_Object -> Next_Light_Source),
  2238.                   &(Parsing_Frame_Ptr -> Light_Sources));
  2239.             }
  2240.          }
  2241.       else if (Temp_Object->Type == COMPOSITE_TYPE)
  2242.          Add_Composite_Light_Source ((COMPOSITE *)Temp_Object);
  2243.       }
  2244.    }
  2245.  
  2246. void Parse_Frame ()
  2247.   {
  2248.   OBJECT *Local_Object;
  2249.  
  2250.   EXPECT
  2251.     CASE (FOG_TOKEN)
  2252.        Parse_Fog();
  2253.     END_CASE
  2254.  
  2255.     CASE (OBJECT_TOKEN)
  2256.       Local_Object = Parse_Object();
  2257.       Link(Local_Object, &(Local_Object -> Next_Object),
  2258.              &(Parsing_Frame_Ptr -> Objects));
  2259.  
  2260.       if (Local_Object -> Light_Source_Flag)
  2261.          Link(Local_Object, &(Local_Object -> Next_Light_Source),
  2262.                &(Parsing_Frame_Ptr -> Light_Sources));
  2263.     END_CASE
  2264.  
  2265.     CASE (COMPOSITE_TOKEN)
  2266.       Local_Object = Parse_Composite();
  2267.       Link(Local_Object, &(Local_Object -> Next_Object),
  2268.             &(Parsing_Frame_Ptr -> Objects));
  2269.  
  2270.       Add_Composite_Light_Source ((COMPOSITE *)Local_Object);
  2271.     END_CASE
  2272.  
  2273.     CASE (VIEW_POINT_TOKEN)
  2274.       Parse_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  2275.     END_CASE
  2276.  
  2277.     CASE (DECLARE_TOKEN)
  2278.       Parse_Declare ();
  2279.     END_CASE
  2280.  
  2281.     CASE (END_OF_FILE_TOKEN)
  2282.       EXIT
  2283.     END_CASE
  2284.  
  2285.     OTHERWISE 
  2286.       Parse_Error (OBJECT_TOKEN);
  2287.     END_CASE
  2288.   END_EXPECT
  2289.   }
  2290.  
  2291. void Parse_Viewpoint (Given_Vp)
  2292.   VIEWPOINT *Given_Vp;
  2293.   {
  2294.   CONSTANT Constant_Id;
  2295.   VECTOR Local_Vector, Temp_Vector;
  2296.   DBL Direction_Length, Up_Length, Right_Length, Handedness;
  2297.  
  2298.   Init_Viewpoint (Given_Vp);
  2299.  
  2300.   EXPECT
  2301.     CASE (IDENTIFIER_TOKEN)
  2302.       if ((Constant_Id = Find_Constant()) != -1)
  2303.         if (Constants[(int)Constant_Id].Constant_Type == VIEW_POINT_CONSTANT)
  2304.           *Given_Vp = 
  2305.              *((VIEWPOINT*) Constants[(int)Constant_Id].Constant_Data);
  2306.         else
  2307.           Type_Error ();
  2308.       else
  2309.         Undeclared ();
  2310.     END_CASE
  2311.  
  2312.     CASE (LOCATION_TOKEN)
  2313.       Parse_Vector(&(Given_Vp -> Location));
  2314.     END_CASE
  2315.  
  2316.     CASE (DIRECTION_TOKEN)
  2317.       Parse_Vector(&(Given_Vp -> Direction));
  2318.     END_CASE
  2319.  
  2320.     CASE (UP_TOKEN)
  2321.       Parse_Vector(&(Given_Vp -> Up));
  2322.     END_CASE
  2323.  
  2324.     CASE (RIGHT_TOKEN)
  2325.       Parse_Vector(&(Given_Vp -> Right));
  2326.     END_CASE
  2327.  
  2328.     CASE (SKY_TOKEN)
  2329.       Parse_Vector(&(Given_Vp -> Sky));
  2330.     END_CASE
  2331.  
  2332.     CASE (LOOK_AT_TOKEN)
  2333.        VLength (Direction_Length, Given_Vp->Direction);
  2334.        VLength (Up_Length, Given_Vp->Up);
  2335.        VLength (Right_Length, Given_Vp->Right);
  2336.        VCross (Temp_Vector, Given_Vp->Direction, Given_Vp->Up);
  2337.        VDot (Handedness, Temp_Vector, Given_Vp->Right);
  2338.        Parse_Vector(&Given_Vp->Direction);
  2339.  
  2340.        VSub (Given_Vp->Direction, Given_Vp->Direction, Given_Vp->Location);
  2341.        VNormalize (Given_Vp->Direction, Given_Vp->Direction);
  2342.        VCross(Given_Vp->Right, Given_Vp->Direction, Given_Vp->Sky);
  2343.        VNormalize (Given_Vp->Right, Given_Vp->Right);
  2344.        VCross (Given_Vp->Up, Given_Vp->Right, Given_Vp->Direction);
  2345.        VScale (Given_Vp->Direction, Given_Vp->Direction, Direction_Length);
  2346.        if (Handedness >= 0.0) {
  2347.           VScale (Given_Vp->Right, Given_Vp->Right, Right_Length);
  2348.           }
  2349.        else {
  2350.           VScale (Given_Vp->Right, Given_Vp->Right, -Right_Length);
  2351.           }
  2352.  
  2353.        VScale (Given_Vp->Up, Given_Vp->Up, Up_Length);       
  2354.     END_CASE
  2355.  
  2356.     CASE (TRANSLATE_TOKEN)
  2357.        Parse_Vector (&Local_Vector);
  2358.        Translate ((OBJECT *) Given_Vp, &Local_Vector);
  2359.     END_CASE
  2360.  
  2361.     CASE (ROTATE_TOKEN)
  2362.        Parse_Vector (&Local_Vector);
  2363.        Rotate ((OBJECT *) Given_Vp, &Local_Vector);
  2364.     END_CASE
  2365.  
  2366.     CASE (SCALE_TOKEN)
  2367.        Parse_Vector (&Local_Vector);
  2368.        Scale ((OBJECT *) Given_Vp, &Local_Vector);
  2369.     END_CASE
  2370.  
  2371.     CASE (END_VIEW_POINT_TOKEN)
  2372.       EXIT
  2373.     END_CASE
  2374.  
  2375.     OTHERWISE
  2376.       Parse_Error (END_VIEW_POINT_TOKEN);
  2377.     END_CASE
  2378.   END_EXPECT
  2379.   }
  2380.  
  2381. void Parse_Declare ()
  2382.   {
  2383.   CONSTANT Constant_Id;
  2384.   TEXTURE *Local_Texture;
  2385.   struct Constant_Struct *Constant_Ptr;
  2386.  
  2387.   GET (IDENTIFIER_TOKEN);
  2388.   if ((Constant_Id = Find_Constant()) == -1)
  2389.     if (++Number_Of_Constants >= MAX_CONSTANTS)
  2390.       Error ("Too many constants \"DECLARED\"");
  2391.     else
  2392.       Constant_Id = Number_Of_Constants;
  2393.  
  2394.   Constant_Ptr = &(Constants[(int)Constant_Id]);
  2395.   GET (EQUALS_TOKEN);
  2396.  
  2397.   EXPECT
  2398.     CASE (OBJECT_TOKEN)
  2399.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2400.       Constant_Ptr -> Constant_Data = (char *) Parse_Object();
  2401.       Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  2402.       EXIT
  2403.     END_CASE
  2404.  
  2405.     CASE (SPHERE_TOKEN)
  2406.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2407.       Constant_Ptr -> Constant_Data = (char *) Parse_Sphere ();
  2408.       Constant_Ptr -> Constant_Type = SPHERE_CONSTANT;
  2409.       EXIT
  2410.     END_CASE
  2411.  
  2412.     CASE (PLANE_TOKEN)
  2413.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2414.       Constant_Ptr -> Constant_Data = (char *) Parse_Plane ();
  2415.       Constant_Ptr -> Constant_Type = PLANE_CONSTANT;
  2416.       EXIT
  2417.     END_CASE
  2418.  
  2419.     CASE (TRIANGLE_TOKEN)
  2420.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2421.       Constant_Ptr -> Constant_Data = (char *) Parse_Triangle ();
  2422.       Constant_Ptr -> Constant_Type = TRIANGLE_CONSTANT;
  2423.       EXIT
  2424.     END_CASE
  2425.  
  2426.     CASE (SMOOTH_TRIANGLE_TOKEN)
  2427.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2428.       Constant_Ptr -> Constant_Data = (char *) Parse_Smooth_Triangle ();
  2429.       Constant_Ptr -> Constant_Type = SMOOTH_TRIANGLE_CONSTANT;
  2430.       EXIT
  2431.     END_CASE
  2432.  
  2433.     CASE (QUADRIC_TOKEN)
  2434.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2435.       Constant_Ptr -> Constant_Data = (char *) Parse_Quadric ();
  2436.       Constant_Ptr -> Constant_Type = QUADRIC_CONSTANT;
  2437.       EXIT
  2438.     END_CASE
  2439.  
  2440.     CASE (QUARTIC_TOKEN)
  2441.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2442.       Constant_Ptr -> Constant_Data = (char *) Parse_Quartic ();
  2443.       Constant_Ptr -> Constant_Type = QUARTIC_CONSTANT;
  2444.       EXIT
  2445.     END_CASE
  2446.  
  2447.     CASE (INTERSECTION_TOKEN)
  2448.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2449.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_INTERSECTION_TYPE, NULL);
  2450.       Constant_Ptr -> Constant_Type = CSG_INTERSECTION_CONSTANT;
  2451.       EXIT
  2452.     END_CASE
  2453.  
  2454.     CASE (UNION_TOKEN)
  2455.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2456.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_UNION_TYPE, NULL);
  2457.       Constant_Ptr -> Constant_Type = CSG_UNION_CONSTANT;
  2458.       EXIT
  2459.     END_CASE
  2460.  
  2461.     CASE (DIFFERENCE_TOKEN)
  2462.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2463.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_DIFFERENCE_TYPE, NULL);
  2464.       Constant_Ptr -> Constant_Type = CSG_DIFFERENCE_CONSTANT;
  2465.       EXIT
  2466.     END_CASE
  2467.  
  2468.     CASE (COMPOSITE_TOKEN)
  2469.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2470.       Constant_Ptr -> Constant_Data = (char *) Parse_Composite();
  2471.       Constant_Ptr -> Constant_Type = COMPOSITE_CONSTANT;
  2472.       EXIT
  2473.     END_CASE
  2474.  
  2475.     CASE (TEXTURE_TOKEN)
  2476.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2477.       Local_Texture = NULL;
  2478.       Constant_Ptr -> Constant_Data = (char *) Local_Texture;
  2479.       Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  2480.       UNGET
  2481.       EXPECT
  2482.          CASE (TEXTURE_TOKEN)
  2483.             Local_Texture = Parse_Texture ();
  2484.             if (Local_Texture->Constant_Flag)
  2485.                Local_Texture = Copy_Texture(Local_Texture);
  2486.  
  2487.             Local_Texture -> Constant_Flag = TRUE;
  2488.  
  2489.             {
  2490.             TEXTURE *temp_texture;
  2491.             for (temp_texture = Local_Texture ;
  2492.                  temp_texture->Next_Texture != NULL ;
  2493.                  temp_texture = temp_texture->Next_Texture)
  2494.                {}
  2495.  
  2496.             temp_texture->Next_Texture = (TEXTURE *) Constant_Ptr->Constant_Data;
  2497.             Constant_Ptr->Constant_Data = (char *) Local_Texture;
  2498.             }
  2499.          END_CASE
  2500.  
  2501.          OTHERWISE
  2502.             UNGET
  2503.             EXIT
  2504.          END_CASE
  2505.       END_EXPECT
  2506.       EXIT
  2507.     END_CASE
  2508.  
  2509.     CASE (VIEW_POINT_TOKEN)
  2510.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2511.       Constant_Ptr -> Constant_Data = (char *) Get_Viewpoint();
  2512.       Constant_Ptr -> Constant_Type = VIEW_POINT_CONSTANT;
  2513.       Parse_Viewpoint((VIEWPOINT *) Constant_Ptr -> Constant_Data);
  2514.       EXIT
  2515.     END_CASE
  2516.  
  2517.     CASE (COLOUR_TOKEN)
  2518.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2519.       Constant_Ptr -> Constant_Data = (char *) Get_Colour();
  2520.       Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  2521.       Parse_Colour ((COLOUR *) Constant_Ptr -> Constant_Data);
  2522.       EXIT
  2523.     END_CASE
  2524.  
  2525.     CASE (LEFT_ANGLE_TOKEN)
  2526.       UNGET
  2527.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2528.       Constant_Ptr -> Constant_Data = (char *) Get_Vector();
  2529.       Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  2530.       Parse_Vector((VECTOR *) Constant_Ptr -> Constant_Data);
  2531.       EXIT
  2532.     END_CASE
  2533.  
  2534.     CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  2535.       UNGET
  2536.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2537.       Constant_Ptr -> Constant_Data = (char *) Get_Float();
  2538.       Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  2539.       *((DBL *) Constant_Ptr -> Constant_Data) = Parse_Float();
  2540.       EXIT
  2541.     END_CASE
  2542.  
  2543.     OTHERWISE
  2544.       Parse_Error (OBJECT_TOKEN);
  2545.     END_CASE
  2546.   END_EXPECT
  2547.   }
  2548.  
  2549. void Init_Viewpoint (vp)
  2550.   VIEWPOINT *vp;
  2551.   {
  2552.   vp -> Methods = (void *) &Viewpoint_Methods;
  2553.   vp -> Type = VIEWPOINT_TYPE;
  2554.   Make_Vector (&vp->Location, 0.0, 0.0, 0.0);
  2555.   Make_Vector (&vp->Direction, 0.0, 0.0, 1.0);
  2556.   Make_Vector (&vp->Up, 0.0, 1.0, 0.0);
  2557.   Make_Vector (&vp->Right, 1.0, 0.0, 0.0);
  2558.   Make_Vector (&vp->Sky, 0.0, 1.0, 0.0);
  2559.   }
  2560.  
  2561. void Link (New_Object, Field, Old_Object_List)
  2562.   OBJECT *New_Object, **Field, **Old_Object_List;
  2563.   {
  2564.   *Field = *Old_Object_List;
  2565.   *Old_Object_List = New_Object;
  2566.   }
  2567.  
  2568. CONSTANT Find_Constant()
  2569.   {
  2570.   register int i;
  2571.  
  2572.   for (i = 1 ; i <= Number_Of_Constants ; i++)
  2573.     if (Constants [i].Identifier_Number == Token.Identifier_Number)
  2574.       return (i);
  2575.  
  2576.   return (-1);
  2577.   }
  2578.  
  2579.  
  2580. char *Get_Token_String (Token_Id)
  2581.   TOKEN Token_Id;
  2582.   {
  2583.   register int i;
  2584.  
  2585.   for (i = 0 ; i < LAST_TOKEN ; i++)
  2586.      if (Reserved_Words[i].Token_Number == Token_Id)
  2587.         return (Reserved_Words[i].Token_Name);
  2588.   return ("");
  2589.   }
  2590.  
  2591. void Parse_Error (Token_Id)
  2592.   TOKEN Token_Id;
  2593.   {
  2594.   char *expected, *found;
  2595.  
  2596.   fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  2597.                                                  Token.Token_Line_No);
  2598.   expected = Get_Token_String (Token_Id);
  2599.   found = Get_Token_String (Token.Token_Id);
  2600.   fprintf (stderr, "%s expected but %s found instead\n", expected, found);
  2601.   exit(1);
  2602.   }
  2603.  
  2604. void Type_Error ()
  2605.   {
  2606.   fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  2607.                                                  Token.Token_Line_No);
  2608.   fprintf (stderr, "Identifier %s is the wrong type\n", Token.Token_String);
  2609.   exit (1);
  2610.   }
  2611.  
  2612. void Undeclared ()
  2613.   {
  2614.   fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  2615.                                                  Token.Token_Line_No);
  2616.   fprintf (stderr, "Undeclared identifier %s\n", Token.Token_String);
  2617.   exit (1);
  2618.   }
  2619.  
  2620. void Error (str)
  2621.   char *str;
  2622.   {
  2623.   fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  2624.                                                  Token.Token_Line_No);
  2625.   fputs (str, stderr);
  2626.   exit (1);
  2627.   }
  2628.  
  2629.